recyclerView中的过滤器列表 编辑

问题描述

我正在使用recyclerView来显示设备中安装的应用程序列表...。请参见下图

图片1-Link

图片2-Link

image 1 desc->在此,我使用弹出菜单过滤已安装和系统的应用程序

image 2 desc->在此,我表明,我使用imageView找出已安装的程序或系统应用程序...这些由Play商店和电话图标分别指示。

问题 ......排序工作正常,我想过滤列表,并可以在该列表上进行排序

我设法借助适配器类中的布尔值和函数将filteredList发送到适配器,适配器类将新列表分配给原始列表,但是排序在那里不起作用

此外,我还使用了滑动操作进行删除,如果我发送新列表... onSwiped方法不会获得新的过滤位置....因为它拥有原始列表适配器位置

MainActivity.kt

   class MainActivity : AppCompatActivity() {

    lateinit var adapter: Adapter  // create adapter instance
    lateinit var applicationList: MutableList<AppData>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        applicationList = getApps(installedApps()) // initialize applicationList variable
        recyclerView.layoutManager = linearlayoutmanager(this)
        adapter = Adapter(applicationList) // initialize adapter variable
        recyclerView.adapter = adapter // pass adapter to recyclerView
        updateNumberOfApps()

        sortList()
        filterList()


    }

  private fun sortList() {
        Sort_List.setonClickListener {
            val popUp = PopupMenu(this,Sort_List)
            popUp.menuInflater.inflate(R.menu.sort_menu,popUp.menu)

            popUp.setonMenuItemClickListener { myItem ->
                when (myItem.itemId) {
                    R.id.Name_ASC -> {
                        applicationList.sortBy { it.name }
                        adapter.notifyDataSetChanged()
                        scrollToTop()
                    }
                }
                true
            }
            popUp.show()
        }
    }

    private fun filterList() {

        Filter_List.setonClickListener {
            val popUp = PopupMenu(this,Filter_List)
            popUp.menuInflater.inflate(R.menu.filter_menu,popUp.menu)

            popUp.setonMenuItemClickListener { myItem ->
                when (myItem.itemId) {
                    R.id.Installed_Apps -> {
                        applicationList.all { it.category }
                        adapter.notifyDataSetChanged()
                        updateNumberOfApps()
                        scrollToTop()
                    }
                    R.id.System_Apps -> {
                   // PROBLEM IS HERE>>>I WANT FILTER AND SORTING WORKING TOGETHER
                       applicationList.sortedBy { it.category }
                        adapter.notifyDataSetChanged()
                        updateNumberOfApps()

                   // here I also manage to send list and assign to adapter like
                   // val list = applicationList.filter { it.category }
                   //  adapter.update(list)
                    }
                }
                true
            }
            popUp.show()
        }
    }

    private fun getApps(List: MutableList<ResolveInfo>): MutableList<AppData> {

        // here I get all apps and return list

        // In this,I also get Boolean value(named category),which return true on system app and false on the installed app
    }
 }
}

Adapter.kt

    class Adapter(private var listofApps: MutableList<AppData>) :
    RecyclerView.Adapter<Adapter.ViewHolder>() {

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

        // call elements from list_apps.xml
        val icon: ImageView = appView.App_icon
        val name: TextView = appView.App_name
        val size: TextView = appView.App_size
    }

    override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(
            R.layout.list_apps,parent,false
        )
        return ViewHolder(view)
    }

    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

       }
    }

// here I declare function which get list from filter method and assign new list to original list
    fun update(newList: MutableList<AppData>){
        listofApps = newList
        notifyDataSetChanged()

    }
}

解决方法

问题是applicationList.all { it.category }不过滤列表。它检查列表并返回true,如果it.category的所有项目都获得true,否则返回false。您应该改用filter

applicationList = applicationList.filter { it.category }

请注意,filter不是就地操作。因此,您应该将其结果设置为applicationList


编辑

您应始终保留当前显示列表的状态,并根据这些状态进行填充。我通过添加两个如下所示的布尔值更改了您的代码:

class MainActivity : AppCompatActivity() {

    lateinit var adapter: Adapter  // create adapter instance
    lateinit var applicationList: MutableList<AppData>

    private val showingApplicationList: MutableList<AppData> = mutableListOf()
    private var isSortedDesc = false
    private var isShowingSystemApps = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        applicationList = getApps(installedApps()) // initialize applicationList variable

        recyclerView.layoutManager = LinearLayoutManager(this)
        adapter = Adapter(showingApplicationList) // initialize adapter variable
        recyclerView.adapter = adapter // pass adapter to recyclerView
        updateNumberOfApps()

        sortList()
        filterList()

        arrangeAppList()
        adapter.update(showingApplicationList)
    }

    private fun sortList() {
        Sort_List.setOnClickListener {
            val popUp = PopupMenu(this,Sort_List)
            popUp.menuInflater.inflate(R.menu.sort_menu,popUp.menu)

            popUp.setOnMenuItemClickListener { myItem ->
                when (myItem.itemId) {
                    R.id.Name_ASC -> {
                        isSortedDesc = false
                        arrangeAppList()
                        adapter.update(showingApplicationList)
                        scrollToTop()
                    }
                    R.id.Name_DESC -> {
                        isSortedDesc = true
                        arrangeAppList()
                        adapter.update(showingApplicationList)
                        scrollToTop()
                    }
                }
                true
            }
            popUp.show()
        }
    }

    private fun filterList() {

        Filter_List.setOnClickListener {
            val popUp = PopupMenu(this,Filter_List)
            popUp.menuInflater.inflate(R.menu.filter_menu,popUp.menu)

            popUp.setOnMenuItemClickListener { myItem ->
                when (myItem.itemId) {
                    R.id.Installed_Apps -> {
                        isShowingSystemApps = false
                        arrangeAppList()
                        adapter.update(showingApplicationList)
                        scrollToTop()
                        updateNumberOfApps()
                    }
                    R.id.System_Apps -> {
                        isShowingSystemApps = true
                        arrangeAppList()
                        adapter.update(showingApplicationList)
                        scrollToTop()
                        updateNumberOfApps()
                    }
                }
                true
            }
            popUp.show()
        }
    }

    private fun arrangeAppList() {
        showingApplicationList.clear()
        showingApplicationList.addAll(
            applicationList.filter { it.category == isShowingSystemApps }
        )
        if (isSortedDesc) {
            showingApplicationList.sortByDescending { it.name }
        } else {
            showingApplicationList.sortBy { it.name }
        }
    }

    private fun getApps(List: MutableList<ResolveInfo>): MutableList<AppData> {

        // here I get all apps and return list

        // In this,I also get Boolean value(named category),which return true on system app and false on the installed app
    }
}