コンセプトLISAビューとリストアダプタのDiffUtil


1.Adapterの役割。


Adapterが演じる役割は、大きく分けて以下の4つに分けられます.
  • xmlの寸法コードをオブジェクトに膨張させると、ビューオブジェクトがViewHolderに再使用されます.
  • RecyclerViewから出力されたデータセットを
  • 画面で管理します.たとえば、データインデックスにアクセスし、出力するデータのViewHolderを変更できます.
  • でClick Eventを管理します.
  • Adapterは、ListViewおよびRecyclerViewのデータをビューにバインドして出力する.
  • 2.LISAクラスタビューとリストアダプタのDiffUtilを使用する場合の違い。


    RecyclerView (setHasStableIds)

    3. DiffUtil.ItemCalbackの解析

    abstract class BaseModel(
        open val id : Long,
        open val type : CellType
    ) {
    
        open fun isTheSame(item: BaseModel) : Boolean {
            return this.id == item.id && this.type == item.type
        }
    
        companion object {
            val DIFF_CALLBACK = object: DiffUtil.ItemCallback<BaseModel>() {
                override fun areItemsTheSame(oldItem: BaseModel, newItem: BaseModel): Boolean {
                    return oldItem.isTheSame(newItem)
                }
    
                @SuppressLint("DiffUtilEquals")
                override fun areContentsTheSame(oldItem: BaseModel, newItem: BaseModel): Boolean {
                    return oldItem == newItem
                }
            }
        }
    }

    上記のコードの「過去」(oldItem)リストと「現在」(newItem)リストの違いを比較することで、「過去」(過去)リストと「現在」(現在)リストを上書きすることを決定します.
    次の図では、各関数の使い方を説明します.
        open fun isTheSame(item: BaseModel) : Boolean {
            return this.id == item.id && this.type == item.type
        }
        
        override fun areItemsTheSame(oldItem: BaseModel, newItem: BaseModel): Boolean {
                    return oldItem.isTheSame(newItem)
        }
                
    areItemsTheSameは、上記のように一意の値をid値と比較して、それらが同じかどうかを決定します.これにより、前のプロジェクトと同じかどうかをテストできます.もしそうであればtrueまたはfalseを返します.
    areItemsTheSameにfalseが表示されると、falseが表示されるアイテムのviewholderが再描画されます.シンチレーションが発生しますtrueを返すと点滅は発生しません.
    falseの例)

    上記の例では全画面が点滅しますが、areItemsTheSameが各エントリidを比較してflaseを返すと、一致しないidだけがviewholderから再描画され、コンテンツが作成されます.したがって、trueを返すidは点滅しません.
        @SuppressLint("DiffUtilEquals")
        override fun areContentsTheSame(oldItem: BaseModel, newItem: BaseModel): Boolean {
            return oldItem == newItem
        }
    areContentsTheSameがareItemsTheSame trueである場合にのみ、areContentsTheSameが呼び出されます.したがって、trueが返されるとviewholderは再描画されないため、データクラスのすべての値を比較して点滅を回避します.比較後に変更したコンテンツ値を更新します.
    trueの例)

    4.Team Project YuMarket応用例


    2つのテストmock dataリストを用意します.
        override fun getAllMarketList(): List<TownMarketModel> {
            val mockList = listOf(
                TownMarketModel(
                    id = 0, "쥬얼리 샵", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.11f
                ),
                TownMarketModel(
                    id = 1, "옷가게", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.22f
                ),
                TownMarketModel(
                    id = 2, "피자스쿨", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.33f
                ),
                TownMarketModel(
                    id = 3, "빅마트", false,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.44f
                ),
                TownMarketModel(
                    id = 4, "롯데리아", false,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.10f
                )
            )
    
            return mockList
        }
    override fun getAllMarketListtest(): List<TownMarketModel> {
            val mockList = listOf(
                TownMarketModel(
                    id = 0, "쥬얼리 샵", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.11f
                ),
                TownMarketModel(
                    id = 1, "옷가게", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.22f
                ),
                TownMarketModel(
                    id = 2, "피자스쿨(test)", true,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.33f
                ),
                TownMarketModel(
                    id = 5, "빅마트(test)", false,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.44f
                ),
                TownMarketModel(
                    id = 4, "롯데리아(test)", false,
                    LocationLatLngEntity(128.0, 36.0),
                    "https://picsum.photos/200", 0.10f
                )
            )
    
            return mockList
        }
    実験を行うために,各データに差がある(test).大手スーパーでのみid値は3->5に変更され、残りはid値は変更されていません.アパレルショップやジュエリーショップはテストを貼っておらず、データが変化しないようにしています.
    まずデータ値を決定し、areContentsTheSameとareItemsTheSameを理解して使用します.

    id値の変換があるため、ビュータイトルを再描画して、大型スーパーでのみ大きな点滅が発生することを確認できます.areContentsTheSameがfalseに戻ったので残りの場合、ピザスクールが少し明るい場合は、タイトルがテストで変更されたため、ビュータイトルを再描画するのではなく、内部のデータ値のみを変換することに気づくかもしれません.

    5. reference


    https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil
    https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter
    https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer
    https://jaeryo2357.tistory.com/70
    https://velog.io/@ilil1/%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-Yu-Market-%EC%B2%AB%EB%B2%88%EC%A7%B8-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-2%ED%8E%B8