관리 메뉴

웹개발자의 기지개

[안드로이드] RecyclerView 실전예제1 - json 내용을 읽어오기 본문

안드로이드

[안드로이드] RecyclerView 실전예제1 - json 내용을 읽어오기

http://portfolio.wonpaper.net 2020. 4. 16. 02:52

위의 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 에 아래의 소스를 한줄 꼭 추가하도록 하자.

1
<uses-permission android:name="android.permission.INTERNET" />
cs

 

 

Comments