Android Recycleview DiffUtil 无法正常工作

问题描述

我在我的应用程序中使用带有 diffutil 的回收视图。但是当我从另一个屏幕旋转或回来时,适配器会更新。为什么会这样?。

这里是我的视图模型

class Feedsviewmodel() : viewmodel() {

    private val FeedsRepository = FeedsRepository()
    val FeedsLiveData: mutablelivedata<Resource<UserFeeds>> = mutablelivedata()
    init {
        val apiParams = HashMap<String,String>()
        apiParams["user_id"] = "1"
        getFeeds(apiParams,"123"
}
    fun getFeeds(apiParams: HashMap<String,String>,token: String) = viewmodelScope.launch {
        FeedsLiveData.postValue(Resource.Loading())
        val response = FeedsRepository.getFeeds(apiParams,token)
        if (response.isSuccessful) {
            response.body()?.let { resultResponse ->
                FeedsLiveData.postValue(Resource.Success(resultResponse))
            }
        } else {
            FeedsLiveData.postValue(Resource.Error(response.message()))

        }
    }
}

我正在使用片段来显示

  override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)
        binding.recyclerViewFeeds.adapter = FeedsAdapter
        viewmodel.FeedsLiveData.observe(viewLifecycleOwner,Observer { response ->
            when (response) {
                is Resource.Success -> {
                    binding.progressBar.visibility = View.GONE
                    response.data?.let { userFeeds ->
                        FeedsAdapter.differ.submitList(userFeeds.userPosts.toList())
                        binding.nooFeeds.visibility = View.GONE
                    }
                is Resource.Error -> {....}
                is Resource.Loading -> {....}
            }
        })
    }

和我的适配器

class FeedsAdapter(private val context: Context,private val itemClickListener: FeedsItemCallBack) :
    RecyclerView.Adapter<FeedsAdapter.MyViewHolder>() {
    class MyViewHolder(val bindin: ItemViewFeedsBinding) : RecyclerView.ViewHolder(bindin.root) {
    }

    private val differCallback = object : DiffUtil.ItemCallback<UserPost>() {
        override fun areItemsTheSame(oldItem: UserPost,newItem: UserPost): Boolean {
            return oldItem.postId == newItem.postId
        }

        override fun areContentsTheSame(oldItem: UserPost,newItem: UserPost): Boolean {
            return oldItem == newItem
        }
    }

    val differ = AsyncListDiffer(this,differCallback)

    override fun onBindViewHolder(holder: MyViewHolder,position: Int) {
        var FeedsItem = differ.currentList[position]
        holder.bindin.FeedData = FeedsItem;
        holder.bindin.executePendingBindings()
    }
    override fun getItemCount(): Int {
        return differ.currentList.size
    }
}

这个实现是否正确?。 这是viewmodel还是适配器的问题? 请帮忙。提前致谢

解决方法

  1. 您可以区分为以下目的创建活动的情况 第一次并从savedInstanceState 恢复。这是 通过覆盖 onSaveInstanceState 并检查参数 onCreate。
  2. 您可以通过添加将活动锁定在一个方向 android:screenOrientation="portrait" (或"landscape") 到 在您的清单中。
  3. 您可以告诉系统您打算处理屏幕更改 为自己指定 android:configChanges="orientation|screenSize" 在 标签。这样,活动将不会被重新创建,但会收到一个 而是回调(您可以忽略它,因为它对您没有用)。

就我个人而言,我会选择 (3)。当然,如果将应用程序锁定到其中一个方向对您来说没问题,您也可以选择 (2)。