๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ‘ฉ‍๐Ÿ’ป TECH

[TECH] RecyclerView ViewModel ์ ์‘๊ธฐ

by yuujoeng 2023. 8. 2.

[ํ‹ฐ๋Œ] ํ‹ฐ๋Œ ๊ฐœ๋ฐœ์ž์˜ RecyclerView ViewModel ์ ์‘๊ธฐ

์•ˆ๋…•ํ•˜์„ธ์š” ํ‹ฐํ”Œ์˜ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž ๊น€์œ ์ •์ž…๋‹ˆ๋‹ค :D
์˜ค๋Š˜์€ ์ง€๋‚œ ํฌ์ŠคํŠธ์—์„œ ๋ง์”€๋“œ๋ ธ๋˜ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ๊ณผ์ •์„ ์†Œ๊ฐœํ•˜๊ณ ์ž ๋Œ์•„์™”์Šต๋‹ˆ๋‹ค!
 


๐Ÿ‘ฉ‍๐Ÿ’ป๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์–ด์š”

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋˜ ๊ฑด ํ‹ฐ๋Œ์˜ ์ฑŒ๋ฆฐ์ง€ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ ์ž…๋‹ˆ๋‹ค.
์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ์ค€๋น„ํ–ˆ๋Š”๋ฐ์š”, ์™ผ์ชฝ์€ ํ˜„์žฌ ํ‹ฐ๋Œ ์„œ๋น„์Šค์ด๊ณ , ์˜ค๋ฅธ์ชฝ์€ ๋‹น์‹œ์˜ ํ™”๋ฉด์ž…๋‹ˆ๋‹ค.
 
๋ฌธ์ œ๊ฐ€ ๋ณด์ด์‹œ๋‚˜์š”? ๋ฐ”๋กœ ์ฑŒ๋ฆฐ์ง€์˜ ๋ฏธ์…˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ œ๋Œ€๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์ฃ !
์•„๋ฌด๋ฆฌ ์ฝ”๋“œ๋ฅผ ๋ณด์•„๋„ ๋ฌธ์ œ๋Š” ๋ณด์ด์ง€ ์•Š๊ณ  ๋˜ ๋งˆ๊ฐ ๊ธฐํ•œ์€ ๋‹ค๊ฐ€์˜ค๊ณ  ์ •๋ง ์ง„๋•€์„ ํ˜๋ ธ๋‹ต๋‹ˆ๋‹ค :<
 

 


๐Ÿ‘ฉ‍๐Ÿ’ป์–ด๋–ค ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ–ˆ์„๊นŒ?

๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € RecyclerView์™€ ViewModel ๊ทธ๋ฆฌ๊ณ  LiveData๋ฅผ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ํ‹ฐ๋Œ์˜ ๊ฐ€๋ณ€ ๋ฆฌ์ŠคํŠธ๋Š” ์œ„์˜ ๊ธฐ์ˆ ๋“ค์„ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ !
 
๋จผ์ € ๐Ÿ“RecyclerView๐Ÿ“๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด์„œ, ๊ฐ ์•„์ดํ…œ์„ ๋ชฉ๋กํ˜•ํƒœ๋กœ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ ์‚ฌ์šฉ๋จ
  • ViewHolder ํŒจํ„ด์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•˜์—ฌ ์Šคํฌ๋กค์‹œ์— ๋ทฐ๋ฅผ ์žฌ์‚ฌ์šฉํ•จ
  • LayoutManager๋ฅผ ํ†ตํ•ด์„œ ๊ฐ ์•„์ดํ…œ์˜ ๋ฐฐ์น˜๋ฅผ ์ˆ˜์ง, ์ˆ˜ํ‰, ๊ฒฉ์ž ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Œ

 
RecyclerView๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์ด ํ•„์š”ํ• ๊นŒ์š”?

  • ์ถœ๋ ฅํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ
  • ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์— ์ •์˜๋œ RecyclerView ์ธ์Šคํ„ด์Šค
  • RecyclerView๋ฅผ ๊ตฌ์„ฑํ•  ์•„์ดํ…œ์˜ ๋ ˆ์ด์•„์›ƒ
  • ์ถœ๋ ฅํ•˜๊ณ ์ž ํ•˜๋Š” ๋ทฐ์˜ ์ •๋ณด๋ฅผ ๋‹ด์€ ViewHolder
  • ๋ฐ์ดํ„ฐ์™€ RecyclerView๋ฅผ ์—ฐ๊ฒฐ ์‹œํ‚ค๊ธฐ ์œ„ํ•œ Adapter

๊ฐ„๋žตํ•˜๊ฒŒ ์ค„์ด์ž๋ฉด, ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” UI ์ปดํฌ๋„ŒํŠธ๋กœ
๐Ÿ“๊ฐ€๋ณ€์ ์ธ ๊ธธ์ด์˜ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์Šคํฌ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค๐Ÿ“
 
 
๋‹ค์Œ์œผ๋กœ โœจViewModelโœจ์€ ์–ด๋–ค ํŠน์ง•์„ ๊ฐ€์งˆ๊นŒ์š”?

  • ์ƒ๋ช… ์ฃผ๊ธฐ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
  • UI ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถ„๋ฆฌ๋˜๋ฏ€๋กœ Configuration ๋ณ€๊ฒฝ(ํ™”๋ฉด ํšŒ์ „ ๋“ฑ)์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
  • ํ”„๋ž˜๊ทธ๋จผํŠธ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ๊ณต์œ ๊ฐ€ ์‰ฌ์›Œ์ง

์œ„์˜ ์ด๋ฏธ์ง€๋Š” Android Activity์™€ ViewModel์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๋น„๊ตํ•œ ๊ฒƒ์ธ๋ฐ์š”,
์ด๋ฏธ์ง€์—์„œ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋“ฏ โœจViewModel์„ ์‚ฌ์šฉํ•˜๋ฉด Activity์™€ ๋…๋ฆฝ์ ์ธ ์ƒ๋ช…์ฃผ๊ธฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹คโœจ
 
๋งˆ์ง€๋ง‰์œผ๋กœ ๐ŸŽLivedata๋Š” ViewModel๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํ•ญ์ƒ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค๋Š” ํŠน์ง•์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค๐ŸŽ


๐Ÿ‘ฉ‍๐Ÿ’ป๋ฌธ์ œ๋Š” ๋ฌด์—‡์ด์—ˆ์„๊นŒ?

์ž! ๊ธฐ๋ฐ˜์ด ๋˜๋Š” ๊ธฐ์ˆ ์„ ์„ค๋ช…ํ–ˆ์œผ๋‹ˆ, ์ •๋ง ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ด์—ˆ๋Š”์ง€ ์•Œ์•„๋ด์•ผ๊ฒ ์ฃ ?
์ฑŒ๋ฆฐ์ง€์— ๋Œ€ํ•œ ๋ฏธ์…˜ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž๋Š” ํŠน์ • ์ฑŒ๋ฆฐ์ง€๋ฅผ ํด๋ฆญํ•œ๋‹ค
  • ํ”„๋ก ํŠธ์—”๋“œ๋Š” ํ•ด๋‹น ์ฑŒ๋ฆฐ์ง€์˜ id ๊ฐ’์„ ๋ฐฑ์—”๋“œ์— ๋ณด๋‚ด ๋ฏธ์…˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ›๋Š”๋‹ค
  • ๋ฆฌ์ŠคํŠธ์˜ ํ•ญ๋ชฉ(๋ฏธ์…˜) ํ•˜๋‚˜ ํ•˜๋‚˜๋ฅผ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ์˜ item์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๋ฅผ ์ƒ์„ฑ ๋ฐ ํ™”๋ฉด์— ์ถœ๋ ฅํ•œ๋‹ค.

๋‹ค์Œ์€ ์‹ค์ œ ๋ฌด์‹ฌ๊ธฐ ์ฑŒ๋ฆฐ์ง€๐Ÿฅฌ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์„œ๋ฒ„์—์„œ ๋ณด๋‚ด์˜จ ๊ฒฐ๊ณผ์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.

{"result":{
"missionList":[{"id":1,"title":"ํ•˜๋ฃจ๋™์•ˆ 0์› ์“ฐ๊ธฐ","required":true,"day":"TUE","check":true},
{"id":2,"title":"์˜ค๋Š˜์˜ ๊ณผ์†Œ๋น„ ๊ธฐ๋กํ•˜๊ธฐ","required":true,"day":"ALL","check":true},
{"id":3,"title":"ํ…€๋ธ”๋Ÿฌ์— ๋งˆ์‹ค ์Œ๋ฃŒ ์‹ธ์„œ ๋‹ค๋‹ˆ๊ธฐ","required":false,"day":"ALL","check":false},
{"id":4,"title":"30๋ถ„ ๋ฏธ๋งŒ ๊ฑฐ๋ฆฌ ์ž์ „๊ฑฐ/๋„๋ณด ์ด์šฉํ•˜๊ธฐ","required":false,"day":"ALL","check":false}]}}

 
ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” ์œ„์˜ ๊ฒฐ๊ณผ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค์— ๋‹ด์•„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

data class ChallengeDetail ( 
	//์ƒ๋žต 
)

data class Result (
	//์ƒ๋žต
    val missionList: List<MissionList>
)

data class MissionList (
    var check: Boolean,
    val day: String,
    val id: Int,
    val required: Boolean,
    val title: String
)

 
์ด์ œ ๋ฐ์ดํ„ฐ์˜ ํšจ์œจ์ ์ธ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ViewModel์„ ์‚ฌ์šฉํ•  ์ฐจ๋ก€์ธ๋ฐ์š”,
์—ฌ๊ธฐ์„œ ์ œ ์‹ค์ˆ˜๊ฐ€ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค!

 

์ฑŒ๋ฆฐ์ง€ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€์˜ View Model ์•ˆ์—์„œ missionList์˜ ์š”์†Œ ํ•˜๋‚˜ ํ•˜๋‚˜๋ฅผ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ์˜ item์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด์ง€๋งŒ
LiveData์— ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ์š”์ฒญ ์ „์ฒด์ธ ChallengeDetail์„ Livedata์— ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋กœ ์ธํ•ด ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๊ฐ€ item์„ ์ œ๋Œ€๋กœ ์ธ์‹ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๊ฒƒ์ด์ฃ .

 
์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ณ ์น˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ต๋‹ˆ๋‹ค.

ChallengeDetailViewModel์—์„œ ๋ฏธ์…˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ž˜ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

 

 


๐Ÿ‘ฉ‍๐Ÿ’ป๋งˆ์น˜๋ฉฐ

RecyclerView์™€ ViewModel ๊ทธ๋ฆฌ๊ณ  LiveData์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์ดํ•ดํ•œ ์ง€๊ธˆ์€ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์ด์ง€๋งŒ,
๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์„ ํ–‰๋˜์ง€ ์•Š์•˜๋˜ ๋‹น์‹œ์—๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ์— ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.
 
์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ๋กœ ๋ฉฐ์น ์„ ๊ณ ๋ฏผํ–ˆ๋‹ค๋‹ˆ - ๋ถ€๋„๋Ÿฝ๊ธฐ๋„ ํ–ˆ์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํšŒ๊ณ ๋ฅผ ๋‚จ๊ธฐ๋Š” ์ด์œ ๋Š”
์•ž์œผ๋กœ๋„ ๊ธฐ์ˆ ์„ ์ ์šฉํ•˜๊ธฐ์— ์•ž์„œ ์ œ๋Œ€๋กœ ๊ณต๋ถ€ํ•˜๊ณ  ์ดํ•ดํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ ์ž ํ•˜๋Š” ๋‹ค์ง์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
 
๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •์— ์ดˆ์ ์„ ๋งž์ถฐ ๊ธ€์„ ์“ฐ๋‹ค๋ณด๋‹ˆ ์„ธ๊ฐ€์ง€ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด ์ œ๋Œ€๋กœ ์†Œ๊ฐœํ•˜์ง€ ๋ชปํ•œ ๊ฒƒ ๊ฐ™์•„
์กฐ๊ธˆ ์•„์‰ฌ์šด ๋งˆ์Œ์ด ๋“œ๋‹ˆ- ๋‹ค์Œ ํฌ์ŠคํŠธ๋Š” ํ•ด๋‹น ๋‚ด์šฉ์„ ์ค€๋น„ํ•ด ์ฐพ์•„์˜ค๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :) !



โฌ‡๏ธ ์ง€๊ธˆ ๊ตฌ๊ธ€ ํ”Œ๋ ˆ์ด ์Šคํ† ์–ด์—์„œ ํ‹ฐ๋Œ ๋‹ค์šด ๋ฐ›๊ธฐ
https://play.google.com/store/apps/details?id=com.team7.tikkle&hl=ko-KR


๐Ÿ“ฉ Contact : yuu-jeong@naver.com
๐Ÿ“ฒ SNS : https://instagram.com/yu.eek