- 파일업로드 유효성체크
- django 엑셀불러오기
- asp.net core Select
- 하드 마이그레이션
- javascript 유효성체크
- asp.net dropdownlist
- ASP.Net Core 404
- php 캐쉬제거
- 강제이동
- 파일업로드 체크
- javascript 바코드 생성
- 하드 윈도우 복사
- 맥 오라클설치
- asp.net Select
- Mac Oracle
- ViewBag
- TempData
- SSD 복사
- javascript 바코드스캔
- 바코드 생성하기
- XSS PHP
- 타임피커
- 바코드 스캔하기
- 404에러페이지
- jquery 바코드생성
- ViewData
- jquery 바코드
- XSS방어
- 말줄임표시
- javascript redirection
웹개발자의 기지개
[안드로이드] RecyclerView 실전예제1 - json 내용을 읽어오기 본문
위의 json 리스트내역 내용을 ReRecyclerView 를 이용하여 아래의 결과 화면 처럼 안드로이드 화면으로 만들어 보자.
우선 json 형태로 리스트 내용을 뽑아오자.
필자는 php 를 이용하여 임의의 json2.php 파일을 아래와 같이 만들어 보았다.
이러한 php 파일로 json 형태의 리스트를 만드는 방법에 관하여 별도의 포스팅 글을 만들어 두었다.
꼭 참고하도록 하자. ( https://wonpaper.tistory.com/213 )
[ json2.php ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<?
header("Content-Type:application/json");
// DB연결설정파일
include "../inc/config.php";
$query = "select * from book_list order by a.goods_no desc limit 20";
$res = mysql_query($query) or die("selecting error!");
if ($res) {
$arr2 = array();
$arr = array();
while ($row = mysql_fetch_object($res)) {
$t = new stdClass();
$t->goods_no = $row->goods_no;
$t->goods_name = $row->goods_name;
$t->sell_price = $row->sell_price;
$t->goods_writer = $row->goods_writer;
$t->goods_detail1 = $row->goods_detail1;
$t->goods_pic1 = $row->goods_pic1;
$arr[] = $t;
unset($t);
}
$arr2['book'] = $arr;
} else {
$arr2 = array(0 => 'empty');
}
echo json_encode($arr2,JSON_PRETTY_PRINT+JSON_UNESCAPED_UNICODE);
?>
|
cs |
위의 소스를 만들었으면 http://각자도메인/json2.php 으로 확인해 보자.
[ Book.java ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
public class Book implements Serializable {
public int goods_no;
public String goods_name;
public int sell_price;
public String goods_writer;
public String goods_detail1;
public String goods_detail2;
public String goods_detail3;
public String goods_pic1;
public String goods_pan;
public Book() { }
public int getGoods_no() {
return goods_no;
}
public void setGoods_no(int goods_no) {
this.goods_no = goods_no;
}
public String getGoods_name() {
return goods_name;
}
public void setGoods_name(String goods_name) {
this.goods_name = goods_name;
}
public int getSell_price() {
return sell_price;
}
public void setSell_price(int sell_price) {
this.sell_price = sell_price;
}
public String getGoods_writer() {
return goods_writer;
}
public void setGoods_writer(String goods_writer) {
this.goods_writer = goods_writer;
}
public String getGoods_detail1() {
return goods_detail1;
}
public void setGoods_detail1(String goods_detail1) {
this.goods_detail1 = goods_detail1;
}
public String getGoods_detail2() {
return goods_detail2;
}
public void setGoods_detail2(String goods_detail2) {
this.goods_detail2 = goods_detail2;
}
public String getGoods_detail3() {
return goods_detail3;
}
public void setGoods_detail3(String goods_detail3) {
this.goods_detail3 = goods_detail3;
}
public String getGoods_pic1() { return goods_pic1;}
public void setGoods_pic1(String goods_pic1) {this.goods_pic1 = goods_pic1;}
}
|
cs |
[ activity_book_list01.xml ] - 기본 xml 레이아웃
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BookList01Activity">
<TextView
android:id="@+id/tv1"
android:text="도서목록"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
|
cs |
[ item.xml ] - RecyclerView 의 한줄 아이템 xml 레이아웃 구성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView1"
android:layout_width="80dp"
android:layout_height="80dp"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/textView2"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:background="@drawable/badgegreen"
android:layout_height="wrap_content">
<TextView
android:text="클릭"
android:padding="4dp"
android:layout_gravity="center|center_vertical"
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/textView4"
android:textColor="@android:color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
|
cs |
[ BookRecyclerAdapter.java ] - RecyclerView 의 Adapter 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class BookRecyclerAdapter extends RecyclerView.Adapter<BookRecyclerAdapter.ItemViewHolder> {
ArrayList<Book> bookList = new ArrayList<Book>();
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder itemViewHolder, int position) {
itemViewHolder.onBind(bookList.get(position));
}
@Override
public int getItemCount() {
return bookList.size();
}
public void addItem(Book book) {
bookList.add(book);
}
class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView textView1;
private TextView textView2;
private TextView textView3;
private TextView textView4;
private ImageView imageView1;
private String imgURL;
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
textView1 = itemView.findViewById(R.id.textView1);
textView2 = itemView.findViewById(R.id.textView2);
textView3 = itemView.findViewById(R.id.textView3);
textView4 = itemView.findViewById(R.id.textView4);
imageView1 = itemView.findViewById(R.id.imageView1);
}
// 실제 데이터를 1개의 객체마다 1:1 대응하여 바인딩시킨다.
void onBind(Book book) {
textView1.setText(book.getGoods_name());
textView2.setText(book.getGoods_writer());
textView3.setText(Integer.toString(book.getSell_price()));
textView4.setText(book.getGoods_detail1());
String imgURL = "http://도메인/pds/goods_data/" + book.getGoods_pic1();
// Glide URL로 이미지 불러오기 오픈소스
Glide.with(itemView).load(imgURL).into(imageView1);
}
}
}
|
cs |
위의 소스에서 이미지를 URL로 그대로 불러오기 위해 오픈소스 Glide 를 사용하였다.
이에 대한 별도의 포스팅을 참고하면 좋을듯하다. ( https://wonpaper.tistory.com/207 )
[ BookList01Activity.java ] - 실제 메인 Activity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class BookList01Activity extends AppCompatActivity {
private BookRecyclerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_list01);
setTitle("json 도서목록 자료 불러오기");
RecyclerView recyclerView1 = findViewById(R.id.recyclerView1);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerView1.setLayoutManager(linearLayoutManager);
recyclerView1.setHasFixedSize(true);
adapter = new BookRecyclerAdapter();
recyclerView1.setAdapter(adapter);
ThreadProc();
}
// 쓰레드 처리
private void ThreadProc() {
new Thread() {
@Override
public void run() {
//super.run();
String str,receiveMsg = "";
String urlStr = "http://각자도메인/json2.php";
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
//conn.setRequestProperty("x-waple-authorization", clientKey);
if (conn.getResponseCode() == conn.HTTP_OK) {
InputStreamReader tmp = new InputStreamReader(conn.getInputStream(), "UTF-8");
BufferedReader reader = new BufferedReader(tmp);
StringBuffer buffer = new StringBuffer();
while ((str = reader.readLine()) != null) {
buffer.append(str);
}
receiveMsg = buffer.toString();
//Log.i("receiveMsg : ", receiveMsg);
reader.close();
Bundle bun = new Bundle();
bun.putString("jsonGap",receiveMsg);
Message msg = handler.obtainMessage();
msg.setData(bun);
handler.sendMessage(msg);
} else {
Log.i("통신 결과", conn.getResponseCode() + "에러");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
private void jsonParsing(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray bookArr = jsonObject.getJSONArray("book");
for (int i=0;i<bookArr.length();i++) {
JSONObject bookObj = bookArr.getJSONObject(i);
Book book = new Book();
book.setGoods_no(Integer.parseInt(bookObj.getString("goods_no")));
book.setGoods_name(bookObj.getString("goods_name"));
book.setSell_price(Integer.parseInt(bookObj.getString("sell_price")));
book.setGoods_writer(bookObj.getString("goods_writer"));
book.setGoods_detail1(bookObj.getString("goods_detail1"));
book.setGoods_pic1(bookObj.getString("goods_pic1"));
// BookRecyclerAdapter에 Book
adapter.addItem(book);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON Parsing Error",e.getMessage());
}
}
/*
Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
//super.handleMessage(msg);
Bundle bun = msg.getData();
String str = bun.getString("jsonGap");
jsonParsing(str);
}
};
*/
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
Bundle bun = msg.getData();
String str = bun.getString("jsonGap");
jsonParsing(str);
return true;
}
});
}
|
cs |
위의 메인 Activity 소소를 보면, 46라인의 내용처럼 http 형태의 json 파일을 직접 읽어서 91라인에서 parsing 하여 RecyclerView 형태로 리스트를 보여주는 실제 소스이다.
이때 http 주소를 그 내용을 직접 읽어 올때에는 쓰레드 형태로 그 항목들을 각각 읽어 와야 한다. 그리고 이 쓰레드를 돌릴때 onCreate함수의 메인쓰레드에서 직접 UI 처리를 할 수가 없다. 이에 그 쓰레드내용 부분에 Handler 라는 놈이 실제 데이터를 처리를 하도록 도와준다.
이러한 쓰레드와 Handler 처리에 대하여 다른 예제 포스팅도 참고하면 좋을듯 하다.
( https://wonpaper.tistory.com/111 )
끝으로 AndroidManifest.xml 에 아래의 소스를 한줄 꼭 추가하도록 하자.
'안드로이드' 카테고리의 다른 글
[안드로이드] Volley 로 웹요청하고 응답받기1 - Get방식 (0) | 2020.04.20 |
---|---|
[안드로이드] 구글맵으로 GPS 현재위치 실시간 연동하기 (12) | 2020.04.18 |
[안드로이드] 배경색의 투명도 (0) | 2020.04.05 |
안드로이드에서 url 주소로 이미지 바로 불러오기 (Glide 사용) (0) | 2020.02.06 |
This Handler class should be static or leaks might occur 시 해결법 (0) | 2020.02.06 |