๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค2024 ์•ˆ๋“œ๋กœ์ด๋“œ/๐Ÿฟ ์˜ํ™” ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ ์ผ์ง€

๐Ÿšจ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ ์Šคํฌ๋กค ์‹œ ๋‚˜ํƒ€๋‚œ ๊ฒฝ๊ณ 

by hyeonha 2024. 10. 13.

๋ชฉ์ฐจ

    ์Šคํฌ๋กค์„ ํ•˜๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝ๊ณ ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

    ์Šคํฌ๋กค ์ฝœ๋ฐฑ์€ ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ์ธก์ •์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ ๋‹จ๊ณ„ ์ค‘์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ณ ,

    ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ์˜ ๊ตฌ์กฐ ๋˜๋Š” ์–ด๋Œ‘ํ„ฐ์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์€ ๋‹ค์Œ ํ”„๋ ˆ์ž„์œผ๋กœ ์—ฐ๊ธฐํ•ด์•ผํ•œ๋‹ค๋Š” ๋‚ด์šฉ์ด์—ˆ๋‹ค.

    Cannot call this method in a scroll callback. 
    Scroll callbacks mightbe run during a measure & layout pass where you cannot change theRecyclerView data. 
    Any method call that might change the structureof the RecyclerView or the adapter contents should be postponed tothe next frame.

     

    ๋‚˜๋Š” ์Šคํฌ๋กค ์ค‘ ์ตœํ•˜๋‹จ์— ๋‹ฟ์œผ๋ฉด ๋‹ค์Œ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค์‹œ ์–ด๋Œ‘ํ„ฐ์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ์ž‘์—…์„ ํ–ˆ๋‹ค.

    ์ด๋•Œ

    1. ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด notifyDataSetChanged()๋ฅผ ํ˜ธ์ถœํ•˜์˜€๊ณ 

    2. ๋กœ๋”ฉ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ์œ„ํ•ด ์–ด๋Œ‘ํ„ฐ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ด์ฃผ์—ˆ๋‹ค.

    ์ด๋กœ ์ธํ•ด ์œ„์™€ ๊ฐ™์€ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ๋œฌ ๊ฒƒ์ด์—ˆ๋‹ค..!!

    // ๊ธฐ์กด 
     is MovieSelectEffect.LoadNextPage -> {
                    Timber.d("4. ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ LoadNextPage effect ํ˜ธ์ถœ ")
                    lifecycleScope.launch {
                        repeatOnLifecycle(Lifecycle.State.STARTED) {
                            viewModel.moviePosterUriList.collect {
                                moviePosterAdapter?.initializePosterUriList()
                                moviePosterAdapter?.setPosterUriList(it)
    
    // ๋ณ€๊ฒฝ View.post(Runnable)์„ ํ†ตํ•ด ๊ตฌํ˜„ํ•ด์ฃผ์—ˆ๋‹ค.
     is MovieSelectEffect.LoadNextPage -> {
                    lifecycleScope.launch {
                        repeatOnLifecycle(Lifecycle.State.STARTED) {
                            viewModel.moviePosterUriList.collect {
                            
                                binding.movieRecyclerView.post {
                                    moviePosterAdapter?.initializePosterUriList()
                                    moviePosterAdapter?.setLoading(false)
                                    moviePosterAdapter?.setPosterUriList(it)
                                    
                                }
                                
    // View.post(Runnble) 
    // UI ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•  ์ž‘์—…์„ ์˜ˆ์•ฝํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
    // ์‹คํ–‰ํ•  ์ž‘์—…์„ UI ์Šค๋ ˆ๋“œ์˜ ์ž‘์—… ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€ํ•œ๋‹ค. ํ˜„์žฌ UI ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„์— ์˜ˆ์•ฝ๋œ ์ž‘์—…์ด ์‹คํ–‰๋œ๋‹ค.
    // UI ์ƒํƒœ๊ฐ€ ์™„์ „ํžˆ ์ค€๋น„๋œ ํ›„  ๋ทฐ ๋ ˆ์ด์•„์›ƒ์ด๋‚˜ ํฌ๊ธฐ ๊ณ„์‚ฐ ํ›„) ์ž‘์—…์ด ์ˆ˜ํ–‰๋œ๋‹ค.
    // ์Šคํฌ๋กค ์ฝœ๋ฐฑ์ด๋‚˜ ๋ฐ์ดํ„ฐ ๋กœ๋“œ ์ค‘ UI์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ”๋กœ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ ๋งž์ง€ ์•Š๋Š” ๋“ฑ ๋ถ€์ž‘์šฉ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
    // post๋ฅผ ํ†ตํ•ด UI ์ž‘์—…์„ ์•ˆ์ „ํ•œ ์‹œ์ ์œผ๋กœ ์—ฐ๊ธฐํ•  ์ˆ˜ ์žˆ๋‹ค.
    
    // ์–ด๋Œ‘ํ„ฐ์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ณ , ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ์ž‘์—…์„ UI ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•˜๋„๋ก ์˜ˆ์•ฝํ•œ๋‹ค.
    // ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์ž‘์—…์ด post๋ฅผ ํ†ตํ•ด ์˜ˆ์•ฝ๋˜๋ฉด , ํ˜„์žฌ ์Šคํฌ๋กค ์ž‘์—… ๋“ฑ์ด ์™„๋ฃŒ๋œ ํ›„ ์‹คํ–‰๋œ๋‹ค.



    728x90