首页 > 解决方案 > RecyclerView 不更新其视图,但更新了 List

问题描述

我正在使用 recyclerView 来显示设备中可用应用程序的列表。此外,我正在使用 bottomSheet 来显示有关所选应用程序的更多详细信息 ...在本节中,我放置了卸载按钮 ...这里我使用卸载代码和来自onActivityResult 方法BottomSheetDialog.kt 文件...按确定...。我想从列表中删除该应用程序/项目并更新视图....此处列表在编码中是正确的,但 recyclerView 不会更新其列表

注意:我调试了代码,发现该列表已在 BottomSheet 文件中更新...我注释掉了 ....但 recyclerView 没有


我在互联网上搜索,但没有找到适合我情况的解决方案


MainActivity.kt

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
   
    
    recyclerView.adapter = Adapter(applicationList) // here I send mutable list of all apps in device to adapter
    recyclerView.layoutManager = LinearLayoutManager(this)


private fun getApps(List: MutableList<ResolveInfo>): MutableList<AppData> {
     // here I return list to adapter with details of installed apps like icon, name, packageName etc
    }

数据类

data class AppData(
val icon: Drawable,
val name: String,
val packageName: String
.....
.....)

适配器.kt

class Adapter(private val listOfApps: MutableList<AppData>) :
RecyclerView.Adapter<Adapter.ViewHolder>() {
 // here I receive mutableList in constructor of Adapter

class ViewHolder(appView: View) : RecyclerView.ViewHolder(appView), View.OnClickListener,
    View.OnLongClickListener {

    init { // initiate both click listeners
        appView.setOnClickListener(this)
        appView.setOnLongClickListener(this)
    }
    // call elements from activity.xml
    val icon: ImageView = appView.App_icon
    val name: TextView = appView.App_name
    val size: TextView = appView.App_size

    override fun onClick(v: View?) {
        Toast.makeText(v?.context, "OnClick", Toast.LENGTH_SHORT).show()

    }

    override fun onLongClick(v: View?): Boolean {
        val bottomSheetDialog = BottomSheetDialog(currentItem, appList) 
        // send currentItem and all List to BottomSheetDialog to show details with the help of function 
       
        // Show bottomSheet on LongPress
        return true
    }

    
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder // done

override fun getItemCount() = listOfApps.size

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    val currentItem = listOfApps[position]
    holder.icon.setImageDrawable(currentItem.icon) 
    holder.name.text = currentItem.name
    holder.size.text = currentItem.size
  }

BottomSheetDialog.kt ......这里在 onActivtyResult 我删除项目并调用通知方法......问题就在这里

class BottomSheetDialog(private val appData: AppData, private val appList: MutableList<AppData>) :
BottomSheetDialogFragment() {
 // here I receive appData and AppList in constructor from Adapter OnLongPress

override fun onCreateView() // done
    
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      
   // here when bottomSheet popup and on click of uninstall.....I check whether user click on OK or CANCEL in onActivity Method (overidden below)
   
     Uninstall_App.setOnClickListener {
        // permission in manifest added
        val intent = Intent(Intent.ACTION_DELETE)
        intent.data = Uri.parse("package:${appData.packageName}")
        intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
        startActivityForResult(intent, 1)
    }

    
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    // get result from uninstall dialog
    if (resultCode == -1) { // ok pressed
        Toast.makeText(context, "ok clicked", Toast.LENGTH_SHORT).show()
        dismiss()

       // here when user pressed OK....delete that item from List
        val index = appList.indexOf(appData)
        appList.removeAt(index)
        Adapter(appList).notifyItemRemoved(index)
        Adapter(appList).notifyDataSetChanged()
        
        // I check above three line by debugging it 
        // 1. val index .. return index of current item
        // 2. this line remove that item
        // 3. Adapter(appList) .... notify Item removed 
        // 4. here that indexed item is removed but view is not updated
        // Note: if it is wrong which is the best method to do this 

    } else if (resultCode == 0) { // cancel pressed
        Toast.makeText(context, "Cancel Click", Toast.LENGTH_SHORT).show()
    }
}

标签: androidkotlinandroid-recyclerview

解决方案


您在这里所做的是创建了两个新适配器(与回收器视图使用的适配器无关,除了适配器的类型相同):

Adapter(appList).notifyItemRemoved(index)
Adapter(appList).notifyDataSetChanged()

您可以创建一个接口来监听来自以下的更改BottomSheetDialog

interface OnAppDeletedListener {
    fun appDeletedAtIndex(index: Int)
}

更新您BottomSheetDialog以接受类型的附加参数OnAppDeletedListener

class BottomSheetDialog(private val appData: AppData, private val appList: MutableList<AppData>, private val listener: OnAppDeletedListener) :
    BottomSheetDialogFragment() {
    
    ...
        
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
            val index = appList.indexOf(appData)
            listener.appDeletedAtIndex(index)  
            dismiss() 
        }
    }
}

更新您的适配器。它必须不负责显示任何对话。Activity 或 Fragment 对此负责。

class Adapter(private val listOfApps: MutableList<AppData>, private val longClickListener: View.OnLongClickListener) :
    RecyclerView.Adapter<Adapter.ViewHolder>() {
     // here I receive mutableList in constructor of Adapter

    class ViewHolder(appView: View) : RecyclerView.ViewHolder(appView), View.OnClickListener {

        init { // initiate both click listeners
            appView.setOnClickListener(this)
            appView.setOnLongClickListener(longClickListener)
        }
        // call elements from activity.xml
        val icon: ImageView = appView.App_icon
        val name: TextView = appView.App_name
        val size: TextView = appView.App_size

        override fun onClick(v: View?) {
            Toast.makeText(v?.context, "OnClick", Toast.LENGTH_SHORT).show()
        }
     }
}

并更新您的活动代码:

 class MainActivity : AppCompatActivity() {

    private lateinit var adapter: Adapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
       
        val longClickListener = object: View.OnLongClickListener {
                override fun onLongClick(v: View?): Boolean {
                    displayAppInfoDialog()
                    return true
                }
            }
        adapter = Adapter(applicationList)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)
    }

    private fun displayAppInfoDialog() {
        val listener = object: OnAppDeletedListener() {
                fun appDeletedAtIndex(index: Int) {
                    adapter.notifyItemRemoved(index)
                }
            }
        val bottomSheetDialog = BottomSheetDialog(currentItem, appList, listener)
        bottomSheetDialog.show()
    }

    ...
}

推荐阅读