Reputation: 92
I am using recyclerView to show list of apps installed in device ....see images below
image 1 - Link
image 2 - Link
image 1 desc --> In this, i use popup menu to filter installed and system apps
image 2 desc --> In this, i showed that, i use imageView to find out which is installed or system app...these are indicated by play store and phone icon resp.
Question is ... sorting is working fine and I want to filter list and can do sort at that list to
somehow I manage to send filteredList to adapter with the help of Boolean value and function in adapter class, which assign new list to original list, but sort is not working there
Moreover, I also used swipe to delete and if I send new list...onSwiped method doesn't get new filtered position....as it hold original list adapterposition
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()
}
}
Upvotes: 0
Views: 936
Reputation: 22832
The problem is that applicationList.all { it.category }
does not filter the list. It checks over the list and returns true
if the it.category
gets true
for all of the items, otherwise it returns false
. You should use filter
instead.
applicationList = applicationList.filter { it.category }
Note that filter
is not an in-place action. So, you should set its result to applicationList
.
You should always keep the state of the current showing list and populate it according to these states. I've changed your code by adding two boolean values like the following:
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
}
}
Upvotes: 2