๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ป Computer/Android

Retrofit2๋กœ ๋ฐ์ดํ„ฐ ๋ฐ›์•„ ์™€์„œ RecyclerView ๋งŒ๋“ค๊ธฐ

์„œ๋ฒ„์—์„œ Jsonํ˜•ํƒœ๋กœ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ RecyclerView๋ฅผ ๋งŒ๋“ค์–ด๋ณด์•˜์—ˆ๋Š”๋ฐ,

3์ผ๊ฐ„ ์ง„์งœ ๋ฐฅ์ž ๋˜ฅ์ด๊ฑฐ๋งŒ ํ–ˆ๋‹ค๊ณ  ํ•ด๋„ ๊ณผ์–ธ์ด ์•„๋‹์ •๋„๋กœ ๋™๋™๊ฑฐ๋ฆฌ๋ฉฐ ๋งŒ๋“ค์—ˆ๋‹ค.

2๋…„ ๋‚ด๋‚ด ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ์–•๊ฒŒ ๋ถ™์žก๊ณ  ์žˆ์—ˆ๋˜ ๊ฒŒ ๋‹ค๋ผ์„œ ๋ญ ํ•˜๋‚˜ ํ• ๋•Œ๋งˆ๋‹ค ์Šค๋ฌด์Šค ํ•˜์ง€๊ฐ€ ์•Š๋‹ค.

์–ด์จŒ๋“  ๋‚˜๊ฐ™์€ ์‚ฌ๋žŒ์ด ํ•œ ๋ช…์ด๋ผ๋„ ์žˆ๋‹ค๋ฉด ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋ฐ”๋žŒ์œผ๋กœ ์—ฌ๊ธฐ์—์„œ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์ค‘๊ฐ„ ์ค‘๊ฐ„์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ธฐ๋„ ํ–ˆ์—ˆ๋Š”๋ฐ

๊ทธ๋•Œ๊ทธ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€๋Š” index๋กœ ์ •๋ฆฌํ•ด์„œ ๋‹ค๋ฅธ ํฌ์ŠคํŠธ์— ๋”ฐ๋กœ ์ •๋ฆฌํ•ด๋‘˜ ๊ฒƒ์ด๋‹ค.

์•”ํŠผ ์Šค๋”ฐ๋šœ! 

*๊ด€๋ จ ๊ฐœ๋…๋“ค์€ ๊ฐœ๋…ํŽธ์— ์ •๋ฆฌํ•ด๋‘ฌ์•ผ์ง•

(๊ฐœ๋…์„ ๋ชจํ˜ธํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ์‰ฝ๊ฒŒ ๊นŒ๋จน์œผ๋‹ˆ๊นŒ ๋ฌด์ž‘์ • ๋”ฐ๋ผํ•˜๊ณ  ๋๋‚ด๊ธฐ ๋ณด๋‹จ ๊ฐœ๋…์„ ํƒ„ํƒ„ํžˆ ํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•œ ๊ฒƒ ๊ฐ™๋‹ค.)

1. build.grade (Module : app)์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

Gradle Scripts -> build.gradle (Module: app)์— retrofit๊ณผ gson converter์„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
dependencies {
    
    ...
 
    // retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
 
    // recyclerview
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
 
 
}
 

 

RecyclerView์„ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€ ๋„์šธ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— RecyclerView๋„ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ค์‹œ๋‹ค.

2. API Client ์ƒ์„ฑํ•˜๊ธฐ

Retrofit์„ ์ด์šฉํ•œ REST API ํ†ต์‹ ์„ ์œ„ํ•ด์„œ๋Š”

1) Retrofit ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๊ณ  2) REST API ๋ช…์„ธ์— ๋งž๋Š” Interface๋ฅผ ์„ ์–ธํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ €, Retrofit ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ApiClient.java ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.retrofit;
 
import retrofit2.Retrofit;
 
public class ApiClient {
 
    public static String BASE_URL = "http://ec2-15-164-234-43.ap-northeast-2.compute.amazonaws.com/";
 
    private static Retrofit retrofit;
    public static Retrofit getClient(){
 
        if(retrofit == null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}
 
 
 

 

static String ๊ฐ’์œผ๋กœ BASE_URL์„ ์ •์˜ํ•ด์ฃผ๋Š” ๋ฐ์š”, "์š”๊ธฐ ์•ˆ์— ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธด ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ์“ฐ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค."

์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ์€ ์ฃผ์†Œ๊ฐ€ ๋ฐ˜๋“œ์‹œ /๋กœ ๋๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด "http://purple/wood/light"๊นŒ์ง€๋งŒ ์ ๋Š”๋‹ค๋ฉด

์‹ค์ œ๋กœ๋Š” "http://purple/wood/"๊นŒ์ง€๋งŒ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค๋Š” ์  ์œ ์˜ํ•ด์ฃผ์„ธ์š”.

์ด๋ฆ„์ด BASE_URL์ธ ๋งŒํผ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋งŒ ์ ์–ด๋‘์‹œ๊ณ  ๋‚˜๋จธ์ง€ ์ฃผ์†Œ๋Š” interface์— ์จ์ค„ ๊ฒ๋‹ˆ๋‹ค!

*์ „์ฒด ์ฃผ์†Œ : http://ec2-15-164-234-43.ap-northeast-2.compute.amazonaws.com/api/restaurant

 

๊ฐ„๋‹จํžˆ retrofit ๊ฐ์ฒด ์ƒ์„ฑ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ ์–ด๋ณด์ž๋ฉด,

retrofit -> retrofit ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•  retrofit ํƒ€์ž…์˜ ๋ณ€์ˆ˜

= new Retrofit.Builder() -> retrofit ๊ฐ์ฒด ์ƒ์„ฑ

.baseUrl(BASE_URL) -> ์–ด๋–ค ์„œ๋ฒ„(BASE_URL)๋กœ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•  ๊ฒƒ์ธ์ง€ ์„ค์ •

.addConverterFactory(GsonConverterFactory.create()) -> ํ†ต์‹  ์™„๋ฃŒ ํ›„, ์–ด๋–ค converter๋กœ ๋ฐ์ดํ„ฐ๋ฅผ parsingํ•  ๊ฒƒ์ธ์ง€

                                                                                     *์•ž์—์„œ gson-converter์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ๋ฏธ๋ฆฌ gradle์— ์ถ”๊ฐ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

.build() -> ํ†ต์‹ ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•œ retrofit ๊ฐ์ฒด ์ƒ์„ฑ ์™„๋ฃŒ-!

์ด๋ ‡๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

3. Data๋ฅผ ๋ฐ›์•„์˜ฌ Class ์ƒ์„ฑํ•˜๊ธฐ

์ œ๊ฐ€ ๊ฐ€์ ธ์˜จ ์„œ๋ฒ„์˜ ์ฃผ์†Œ๋ฅผ ๋“ค์–ด๊ฐ€๋ณด๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ 

 

{"statusCode":200,"serverTime":1583501031307,"body":[{"id":1,"name":"TEST","locLatitude":123.123456,"locLongitude":123.456789,"numOfStar":0,"numOfLike":0},{"id":2,"name":"๋‘๋ฒˆ์งธ ๋ฐ์ดํ„ฐ","locLatitude":111.054869,"locLongitude":120.3154,"numOfStar":0,"numOfLike":0},{"id":3,"name":"ํ•œ์–‘๋Œ€ํ•™๊ต ์„œ์šธ์บ ํผ์Šค","locLatitude":37.557394,"locLongitude":127.045354,"numOfStar":1234,"numOfLike":5678},{"id":4,"name":"ํƒ•ํ™”์ฟตํ‘ธ ๋งˆ๋ผํƒ•","locLatitude":37.560946,"locLongitude":127.046428,"numOfStar":1000,"numOfLike":2000}]}

 

์š”๋ ‡๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด {"A" : 1, "B" : 2, "C" : [{"a":10, "b":20", "c":30, "d":40}]} ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์–ด์š”!

์ฆ‰, ์ค‘๊ด„ํ˜ธ ์† ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ์ค‘๊ด„ํ˜ธ๊ฐ€ ๋˜ ์žˆ๋Š” ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ •ํ™•ํžˆ ์•Œ์•„์•ผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ํ—ค๋งค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ํด๋ž˜์Šค๋ฅผ ๋‘ ๊ฐœ ๋งŒ๋“ค๊ฑฐ์—์š”.

์ด๊ฑฐ ์ž๊พธ ๊นจ์ ธ์„œ ๊ฑ ์บก์ณํ•ด์„œ ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค

TestItem์€ ๊ฒ‰์— ์‹ผ ์ค‘๊ด„ํ˜ธ์˜ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค์ด๊ณ  Data๋Š” ์•ˆ์— ์žˆ๋Š” ์ค‘๊ด„ํ˜ธ์˜ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค์—์š”.

TestItem์„ ๋ณด๋ฉด ์„ธ๋ฒˆ์งธ ๋ณ€์ˆ˜๋กœ List<Data> body;๊ฐ€ ์žˆ์ฃ .

์—ฌ๊ธฐ์„œ Data๊ฐ€ ์˜ค๋ฅธ์ชฝ ํด๋ž˜์Šค์ด๊ณ , "id, name, locLatitude, locLongitude, numOfStar, numOfLike"๊ฐ€ ๋ฆฌ์ŠคํŠธํ˜•ํƒœ๋กœ

TestItem์˜ body์— ํ•˜๋‚˜์”ฉ ๋“ค์–ด๊ฐ€์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ์ดํ•ดํ•˜๊ธฐ ํŽธํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ํ‹€๋„ ์ค€๋น„๋๊ณ , Retrofit ๊ฐ์ฒด๋„ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ Interface๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ†ต์‹ ์„ ์œ„ํ•ด์„œ์š”!

+) TestItem ํด๋ž˜์Šค์—๋Š” toString()๋ฉ”์†Œ๋“œ๋„ ์ •์˜ํ•ด๋‘์—ˆ์–ด์š”! 5๋ฒˆ ๋‹จ๊ณ„์—์„œ ๋กœ๊ทธ๋ฅผ ์ฐ์„ ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

4. API Interface ์ƒ์„ฑํ•˜๊ธฐ

์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ญ”๊ฐ€์š”? ํด๋ž˜์Šค๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š” ๋™์ž‘์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ผ์ข…์˜ ์ถ”์ƒํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค์—ˆ๋˜ API Client ์žˆ์ฃ ? ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ๋ฐ›์•„์˜ค๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜์ฃ .

๊ทธ๋Ÿฌ๋ฉด ์„œ๋ฒ„์—์„œ ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ , ์–ด๋–ป๊ฒŒ ๋ฐ›์„์ง€ ์ธํ„ฐํŽ˜์ด์Šค์— ๋ช…์‹œ์— ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
 
public interface ApiInterface {
 
    @GET("api/restaurant")
    Call<TestItem> getData();
 
}
 

 

์œ„ ์ธํ„ฐํŽ˜์ด์Šค๋Š” REST API ๋ช…์„ธ์— ๋งž๊ฒŒ ์ž‘์„ฑํ•˜์—ฌ ์„ ์–ธํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Retrofit์—์„œ๋Š” REST API ํ†ต์‹ ์— ํ•„์š”ํ•œ Annotation์„ ๋งŒ๋“ค์–ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

 

์œ„์—์„œ ์ €๋Š” @GET Anotation์„ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ์š”,

์ด ๊ฒฝ์šฐ HTTPํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์†Œ๋“œ ์ค‘ GET ์š”์ฒญ์„ ํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

@GET์™ธ์—๋„ @POST @PUT @DELETE @HEAD ์ด๋ ‡๊ฒŒ ์ด 5๊ฐœ์˜ Annotation์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Anotation ๊ด„ํ˜ธ ์•ˆ์—๋Š” ์•„๊นŒ ์ „์ฒด ์ฃผ์†Œ์—์„œ BASE_URL ๋ถ€๋ถ„์„ ๋บ€ ๋‚˜๋จธ์ง€ ์ฃผ์†Œ๋ฅผ ์ ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์ •๋ฆฌํ•˜์ž๋ฉด, @์ฃผ์„(API URL)ํ˜•ํƒœ๋ฅผ ํ†ตํ•ด์„œ ์‹ค์งˆ์ ์œผ๋กœ ์–ด๋–ค API ์ฃผ์†Œ์—์„œ ์–ด๋–ค ๋ฉ”์†Œ๋“œ๋ฅผ ์š”์ฒญํ•  ๊ฒƒ์ธ์ง€ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ GETํ•˜๊ธฐ ์œ„ํ•ด GET anotation์„ ์“ด ๊ฒƒ์ด๊ตฌ์š”.

 

์ด์ œ ์„œ๋ฒ„์— ํ†ต์‹  ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  GET์š”์ฒญ์„ ํ–ˆ๊ณ , ์ด์ œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค ํ˜•ํƒœ๋กœ ๋‹ด์•„๋‘˜ ๊ฒƒ์ธ์ง€ ๋ช…์‹œํ•ด์ฃผ์–ด์•ผ๊ฒ ์ฃ .

์œ„์— ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค ํด๋ž˜์Šค์— ๋‹ด์„ ๊ฑด์ง€ ๋ฏธ๋ฆฌ ๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋ฅผ ๋ณด๊ณ  ์ง€์ •์„ ํ•ด๋†“์•˜์œผ๋‹ˆ

ํฐ ๊ทธ๋ฆ‡์ธ TestItem์— ๋‹ด๊ธฐ๋กœ ํ•ฉ์‹œ๋‹ค.

Call<ํ˜•ํƒœ> getData(); ์ด๋ ‡๊ฒŒ ์จ์ฃผ๋ฉด <ํ˜•ํƒœ>์— ๋งž๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์„œ getData()๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๋ฉด๋ฉ๋‹ˆ๋‹ค.

5. MainActivity.class์— ํ†ต์‹ ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ธํŒ…ํ•ด์ฃผ๊ธฐ

์ž, ์ด์ œ ํ†ต์‹ ์„ ์œ„ํ•œ ์ค€๋น„๋ฅผ ๋งˆ์ณค์œผ๋ฉด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ์š”๋ฆฌ์กฐ๋ฆฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ Interface์™€ Retrofit ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ HTTP ํ†ต์‹ ์„ ์š”์ฒญํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ด์ง€์š”.

์ผ๋‹จ, MainActivity์— ์„ธํŒ…์„ ํ•˜๋ฉด์„œ TestItem ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ๋ฐ›์•„์˜ค๋Š” ์ง€ ํ™•์ธ์„ ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”.

 

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
public class MainActivity extends AppCompatActivity {
 
    TestItem dataList;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
 
        Call<TestItem> call = apiInterface.getData();
 
        call.enqueue(new Callback<TestItem>() {
 
            @Override
            public void onResponse(Call<TestItem> call, Response<TestItem> response) {
 
                dataList = response.body();
 
                Log.d("MainActivity", dataList.toString());
            }
 
            @Override
            public void onFailure(Call<TestItem> call, Throwable t) {
 
                Log.d("MainActivity", t.toString());
            }
        });
    }
}
 

 

Line 3 : ์šฐ์„  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ TestItem ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ „ ๋ณ€์ˆ˜๋ช…์„ dataList๋กœ ์ง€์—ˆ์–ด์š”.

Line 10 : ์œ„์—์„œ ์ •์˜ํ•ด๋‘” Interface๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

Line 12 : ํ†ต์‹  ํ›„ ์‘๋‹ต์„ ๋ฐ›์„ Callback์„ ๊ตฌํ˜„ํ•ด์ค๋‹ˆ๋‹ค. Interface์— ๋ช…์‹œํ•œ Callํ•˜๊ณ  ๊ฐ™์ฃ ?

            TestItemํ˜•ํƒœ๋กœ ์‘๋‹ต์„ ๋ฐ›์„ ์นœ๊ตฌ๋ฅผ call์ด๋ผ๊ณ  ๋ช…๋ช…ํ•ด์ฃผ๊ณ  apiInterface.getData()๋กœ ์‘๋‹ต์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

Line 14 : Client ๊ฐ์ฒด๊ฐ€ ์ œ๊ณตํ•˜๋Š” enqueue ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํ†ต์‹ ์— ๋Œ€ํ•œ ์š”์ฒญ ๋ฐ ์‘๋‹ต์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

            ์„ฑ๊ณตํ•  ๊ฒฝ์šฐ์—๋Š” onResponse๋กœ ๋“ค์–ด๊ฐ€๊ณ , ์‹คํŒจํ•  ๊ฒฝ์šฐ์—๋Š” onFailure๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

            ๊ฐ๊ฐ์˜ ๊ฒฝ์šฐ์— Log์— Log.d()๊ด„ํ˜ธ ์•ˆ์— ๋‚ด์šฉ์ด ์ถœ๋ ฅ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Line 19 : dataList์— response.body();๋ฅผ ํ†ตํ•ด Call(์š”์ฒญ)์— ๋Œ€ํ•œ Response(์‘๋‹ต)๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

Line 20 : Log.d์—์„œ dataList.toString()์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๊ฒŒ ๋˜๊ฒ ์ฃ ?

 

๋งจ ๋ฐ‘์ค„์„ ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

6. RecyclerView๋กœ ๋ฐ์ดํ„ฐ ๋„์šฐ๊ธฐ

6-1. RecyclerView ๋ ˆ์ด์•„์›ƒ ๋งŒ๋“ค๊ธฐ

RecyclerView๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋„์šฐ๋ ค๋ฉด RecyclerView๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ๊ฒ ์ฃ ?

๋จผ์ € ๋ ˆ์ด์•„์›ƒ ๋‘ ๊ฐœ๋ฅผ ๋งŒ๋“ค๊ฒ๋‹ˆ๋‹ค. Recyclerํ•˜๊ฒŒ ๋ชฉ๋ก์„ ๋„์šธ ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ๊ณผ

๋ชฉ๋ก ํ•˜๋‚˜ํ•˜๋‚˜, ์ฆ‰ View ํ–‰ ํ•˜๋‚˜์˜ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค๊ฒ๋‹ˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
 
 
 

์œ„ ์ฝ”๋“œ๋Š” ๋ฆฌ์‚ฌ์ดํด๋ทฐ๊ฐ€ ์˜ฌ๋ผ๊ฐˆ ํ™”๋ฉด์ž…๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ id๋Š” recyclerView๋กœ ์ง€์ •ํ•ด์ฃผ์—ˆ์–ด์š”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
 
    <TextView
        android:id="@+id/dataName"
        android:layout_width="0dp"
        android:layout_weight="4"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:layout_margin="10dp"
        android:textAlignment="center"
        android:text="restaurant"/>
 
</LinearLayout>
 

์ด๊ฑฐ๋Š” ํ–‰ ํ•˜๋‚˜์˜ ๋ ˆ์ด์•„์›ƒ์ด์—์š”. android:layout_weight๊ฐ€ ์žˆ๋Š” ๊ฑธ ๋ณด๋ฉด ๊ฐ์ด ์˜ค์‹œ๋‹ค์‹œํ”ผ ์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ์ค„์˜€๋Š”๋ฐ, ์ €๋Š” 4:1:1๋น„์œจ๋กœ ์ฒซ ์นธ์—๋Š” name, ๋‘๋ฒˆ์งธ์นธ์—๋Š” numOfStar, ์„ธ๋ฒˆ์งธ์นธ์—๋Š” numOfLike๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•ด TextView๋ฅผ ๋ฐฐ์น˜ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์š”๋Ÿฐ์‹์œผ๋กœ ๋‚˜์˜ค๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ์š”!

6-2. RecyclerView Adapter ๋งŒ๋“ค๊ธฐ

RecyclerView๋Š” ListView์™€ ๋‹ค๋ฅด๊ฒŒ ํ•œ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ ํž˜๋“  ๋‹ค์ˆ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์Šคํฌ๋กค์ด ๊ฐ€๋Šฅํ•œ list๋กœ view๋ฅผ ์žฌํ™œ์šฉํ•ด ํ‘œ์‹œํ•ด์ฃผ๋Š” ์œ„์ ฏ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ํ‹€์„ ์žฌํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด Adapter๋กœ itemView๋ฅผ ๋งŒ๋“ค์–ด๋‚ด์„œ ์‚ฌ์šฉํ•˜์ฃ .

์•„๋ž˜์— ๋ณด์—ฌ๋“œ๋ฆฌ๋Š” ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ๋œฏ์–ด์„œ ์ž์„ธํžˆ ์—ญํ•  ์„ค๋ช…์„ ํ•˜๋Š” ๊ฒƒ์€ RecyclerView ์ „์šฉ ํฌ์ŠคํŠธ์—์„œ ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ธฐ๋กœ ํ•˜๊ณ  ์šฐ์„ ์€ ์š”๊ธฐ์— ์ง‘์ค‘์„ ํ•ด๋ด…์‹œ๋‹ค.

 

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
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>{
 
    private Context c;
    private List<Data> dataList;
 
    public RecyclerAdapter(Context c, List<Data> dataList) {
        this.c = c;
        this.dataList = dataList;
    }
 
    @NonNull
    @Override
    public RecyclerAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 
        return new MyViewHolder(view);
    }
 
    @Override
    public void onBindViewHolder(@NonNull RecyclerAdapter.MyViewHolder holder, int position) {
 
        holder.numOfStar.setText("" + dataList.get(position).getNumOfStar());
        holder.numOfLike.setText("" + dataList.get(position).getNumOfLike());
 
    }
 
    @Override
    public int getItemCount() {
        return dataList.size();
    }
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
 
        TextView name;
        TextView numOfStar;
        TextView numOfLike;
 
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
 
            name = (TextView)itemView.findViewById(R.id.dataName);
            numOfStar = (TextView)itemView.findViewById(R.id.dataNumOfStar);
            numOfLike = (TextView)itemView.findViewById(R.id.dataNumOfLike);
 
        }
    }
}
 

์ €๋Š” ์œ„ ๋ฐ์ดํ„ฐ์—์„œ id, locLatitude, locLongitude๋ฅผ ๋นผ๊ณ  name์ด๋ž‘ numOfStar, numOfLike๋งŒ ๋ฐ›์•„์„œ ๋„์šฐ๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— Adapter๋ฅผ ๋งŒ๋“ค๋•Œ ์•„์˜ˆ itemView์— ์ด ์„ธ ๊ฐ€์ง€๋งŒ ๋„ฃ์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

RecyclerView๋ฅผ ์œ„ํ•œ Adapter๋Š” ์ด๋Ÿฐ ํ˜•ํƒœ์ธ๋ฐ ์ฒ˜์Œ์— RecyclerView๋ฅผ ๋งŒ๋“ค ๋• Holder ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์—ˆ์—ˆ๋Š”๋ฐ ๊ฐ™์ด ๋งŒ๋“œ๋Š” ๊ฒŒ ๋” ํŽธํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Holder๋Š” ๋ ˆ์ด์•„์›ƒ๊ณผ ์—ฐ๊ฒฐํ•ด์„œ itemView๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ด์š”. (๋‹จ์ˆœ ์—ฐ๊ฒฐ)

Adapter์—์„œ๋Š” Holder์—์„œ ๋งŒ๋“ค์–ด์ค€ itemView๋ฅผ inflater์„ ์ด์šฉํ•ด ๊ฐ์ฒดํ™” ์‹œํ‚ค๊ณ , ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์ค๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•ด, Holder๋กœ itemView๊ทธ๋ฆ‡์„ ๋งŒ๋“ค๋ฉด Adapter๊ฐ€ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ itemView๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฑฐ์ฃ !

๊ทธ ๊ณผ์ •์—์„œ inflater๋Š” xml์„ ๊ฐ์ฒดํ™”์‹œํ‚ค๋Š” ๊ฑธ ๋•๊ณ , layoutManager์€ recyclerview์— ์ฐจ๋ก€์ฐจ๋ก€ ๋„์šฐ๋Š” ๊ฑธ ๋„์™€์ค๋‹ˆ๋‹ค.

6-3. RecyclerView ์‚ฌ์šฉํ•˜๊ธฐ

์ด์ œ RecyclerView๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋งŒ๋ฐ˜์˜ ์ค€๋น„๋ฅผ ๋๋ƒˆ์œผ๋‹ˆ, MainActivity๋กœ ๋Œ์•„๊ฐ€์„œ ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

 

1
2
3
4
5
6
7
public class MainActivity extends AppCompatActivity {
 
    TestItem dataList;
    List<Data> dataInfo;
 
    RecyclerView recyclerView;
    RecyclerAdapter recyclerAdapter;
 

์šฐ์„  MainAcitivity ์•ˆ์— ์ด๋ ‡๊ฒŒ RecyclerView์™€ Adapter ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

 

์•—! List<Data> dataInfo;๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒŒ ๋ณด์ด์‹œ๋‚˜์š”? ๊ธฐ์กด์˜ TestItem dataList; ์•„๋ž˜์—์š”!

์ €๋Š” ์ด๊ฑฐ ํ•  ๋•Œ ์ค‘๊ด„ํ˜ธ ์† ์ค‘๊ด„ํ˜ธ ์•ˆ์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค ์ค‘ ๋ช‡ ๊ฐœ๋ฅผ ๊ณจ๋ผ์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€๋ฐ, 

์ด๊ฑธ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜ ํ•˜๋ฉด์„œ ์ •๋ง ํ—ค๋งธ์—ˆ์–ด์š”.

๊ธฐ์ดˆ๊ฐ€ ๋ถ€์กฑํ•œ ํƒ“์ธ์ง€, ๊ธฐ์ดˆ์ ์ธ ๊ฑธ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ํƒ“์ธ์ง€ ๋งŽ์ด ํ—ค๋งธ์—ˆ๋Š”๋ฐ

์–ด์จŒ๋“  ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์œผ๋‹ˆ ๊ณต์œ ํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

์ค‘๊ด„ํ˜ธ ์† ์ค‘๊ด„ํ˜ธ ๋‚ด์šฉ๋“ค์„ ๋‹ด์„ ํด๋ž˜์Šค๋ฅผ Data.class๋กœ ๋งŒ๋“ค์–ด์คฌ์—ˆ์ฃ ? ๊ทธ๊ฑธ ๋ฆฌ์ŠคํŠธ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด

์ €๋ ‡๊ฒŒ dataInfo๋ผ๋Š” ์ด๋ฆ„์˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์คฌ์–ด์š”!

 

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
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        dataInfo = new ArrayList<>();
        recyclerView = findViewById(R.id.recyclerView);
 
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
 
        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
 
        Call<TestItem> call = apiInterface.getData();
 
        call.enqueue(new Callback<TestItem>() {
            @Override
            public void onResponse(Call<TestItem> call, Response<TestItem> response) {
 
                dataList = response.body();
 
                Log.d("MainActivity", dataList.toString());
 
                dataInfo = dataList.body;
 
                recyclerAdapter = new RecyclerAdapter(getApplicationContext(), dataInfo);
                recyclerView.setAdapter(recyclerAdapter);
 
            }
 
 

 

onCreate์•ˆ์—์„œ ๋ณธ๊ฒฉ์ ์œผ๋กœ RecyclerView์— ๋„์šธ ์ค€๋น„๋ฅผ ํ•  ๊ฑฐ์—์š”.

Line 6 : dataInfo๋ผ๋Š” ๋ณ€์ˆ˜๋กœ ์ƒˆ๋กœ์šด ArrayList<>๋ฅผ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค.

 

Line 9&10 : ๊ทธ๋ฆฌ๊ณ  ์•ž์„œ ์„ค๋ช…๋“œ๋ฆฐ LayoutManager์„ ์ด์šฉํ•˜์—ฌ RecyclerView๋ฅผ ์„ธํŒ…ํ•ด์ค๋‹ˆ๋‹ค.

Line 24 : Call(์š”์ฒญ)์— ๋Œ€ํ•œ Response(์‘๋‹ต)๋ฅผ dataList๋ผ๋Š” TestItemํ˜•ํƒœ์˜ ๊ฐ์ฒด์— ๋‹ด์•˜์ž–์•„์š”?

            ๊ทธ๋Ÿฌ๋ฉด ๊ทธ dataList์— ๋‹ด๊ธด body part, ์ฆ‰ List<Data>๋ฅผ ๋ฝ‘์•„์˜ค๊ธฐ ์œ„ํ•ด dataInfo = dataList.body;๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.

            *์—ฌ๊ธฐ์„œ response.body()์—์„œ์˜ body()ํ•จ์ˆ˜์™€ body๋ฅผ ํ—ท๊ฐˆ๋ฆฌ๋ฉด ์•ˆ๋˜์š”!

             ํ›„์ž์˜ body๋Š” ์ œ๊ฐ€ ๋ฐ›์•„์˜ค๋Š” ๋ฐ์ดํ„ฐ ๋‚ด์—์„œ์˜ ๋ณ€์ˆ˜๋ช…์ž…๋‹ˆ๋‹ค!! ใ…  ใ…… ใ… 

 

Line 26 : ์ด์ œ Adapter๋ฅผ ์ด์šฉํ•ด์„œ dataInfo์— ์žˆ๋Š” ๋‚ด์šฉ์„ ๊ฐ€์ ธ์™€์„œ ์ง€์ •ํ•ด๋‘” itemView ํ˜•์‹์— ๋งž๊ฒŒ ๋„์šฐ๊ฒŒ ๋  ๊ฒ๋‹ˆ๋‹ค!

 

 

์จ”์ง !!

์œ„์—์„œ ๋ดค๋˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋ณด์—ฌ๋“œ๋ฆฌ์ž๋ฉด

 

{"statusCode":200,"serverTime":1583501031307,"body":[{"id":1,"name":"TEST","locLatitude":123.123456,"locLongitude":123.456789,"numOfStar":0,"numOfLike":0},{"id":2,"name":"๋‘๋ฒˆ์งธ ๋ฐ์ดํ„ฐ","locLatitude":111.054869,"locLongitude":120.3154,"numOfStar":0,"numOfLike":0},{"id":3,"name":"ํ•œ์–‘๋Œ€ํ•™๊ต ์„œ์šธ์บ ํผ์Šค","locLatitude":37.557394,"locLongitude":127.045354,"numOfStar":1234,"numOfLike":5678},{"id":4,"name":"ํƒ•ํ™”์ฟตํ‘ธ ๋งˆ๋ผํƒ•","locLatitude":37.560946,"locLongitude":127.046428,"numOfStar":1000,"numOfLike":2000}]}

 

์ด๋ ‡๊ฒŒ ์ƒ๊ฒจ๋จน์€ ๋ฐ์ดํ„ฐ์˜€์ฃ ? ์—ฌ๊ธฐ์„œ name, numOfStar, numOfLike๋ถ€๋ถ„๋งŒ ๊ฐ€์ ธ์˜จ ๊ฑฐ์—์š”!

์Œฉ์ดˆ๋ณด๊ฐ€ ํ•˜๊ธฐ์— 3์ผ ๊ฐ„ ์–ด๋ ค์›€์ด ๋งŽ์•˜์ง€๋งŒ ์™„์„ฑํ•˜๊ณ  ๋‚˜๋‹ˆ ๋ฟŒ๋“ฏํ–ˆ์—ˆ์–ด์š”.

์šฐ์—ฐํžˆ ๋ธ”๋กœ๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•œ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž‘์€ ๋„์›€์ด๋‚˜๋งˆ ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋„ค์š”.

์–ด์ฉŒ๋‹ค๋ณด๋‹ˆ ๊ตฌ์–ด์ฒด๊ฐ€ ๋˜์—ˆ๋Š”๋ฐ, ์จ‹๋“  ๋!!

๋ฐ˜์‘ํ˜•