mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-19 21:08:28 +00:00
Cleanup filterable list implementation
This commit is contained in:
parent
d130aa02a1
commit
382568bd3c
@ -1,55 +1,38 @@
|
||||
package com.topjohnwu.magisk.databinding
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Looper
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.Collections
|
||||
|
||||
class FilterableDiffObservableList<T>(
|
||||
callback: Callback<T>
|
||||
callback: Callback<T>,
|
||||
private val scope: CoroutineScope
|
||||
) : DiffObservableList<T>(callback) {
|
||||
|
||||
var filter: ((T) -> Boolean)? = null
|
||||
set(value) {
|
||||
field = value
|
||||
queueUpdate()
|
||||
}
|
||||
@Volatile
|
||||
private var sublist: MutableList<T> = super.list
|
||||
private var sublist: MutableList<T> = list
|
||||
private var job: Job? = null
|
||||
|
||||
// ---
|
||||
|
||||
private val ui by lazy { Handler(Looper.getMainLooper()) }
|
||||
private val handler = Handler(HandlerThread("List${hashCode()}").apply { start() }.looper)
|
||||
private val updater = Runnable {
|
||||
val filter = filter ?: { true }
|
||||
val newList = super.list.filter(filter)
|
||||
val diff = synchronized(this) { doCalculateDiff(sublist, newList) }
|
||||
ui.post {
|
||||
sublist = Collections.synchronizedList(newList)
|
||||
diff.dispatchUpdatesTo(listCallback)
|
||||
fun filter(filter: (T) -> Boolean) {
|
||||
job?.cancel()
|
||||
job = scope.launch(Dispatchers.Default) {
|
||||
val newList = list.filter(filter)
|
||||
val diff = synchronized(this) { doCalculateDiff(sublist, newList) }
|
||||
withContext(Dispatchers.Main) {
|
||||
sublist = Collections.synchronizedList(newList)
|
||||
diff.dispatchUpdatesTo(listCallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun queueUpdate() {
|
||||
handler.removeCallbacks(updater)
|
||||
handler.post(updater)
|
||||
}
|
||||
|
||||
fun hasFilter() = filter != null
|
||||
|
||||
fun filter(switch: (T) -> Boolean) {
|
||||
filter = switch
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
filter = null
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
override fun get(index: Int): T {
|
||||
return sublist.get(index)
|
||||
return sublist[index]
|
||||
}
|
||||
|
||||
override fun add(element: T): Boolean {
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.topjohnwu.magisk.databinding
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
fun <T : AnyDiffRvItem> diffListOf() =
|
||||
DiffObservableList(DiffRvItem.callback<T>())
|
||||
|
||||
fun <T : AnyDiffRvItem> filterableListOf() =
|
||||
FilterableDiffObservableList(DiffRvItem.callback<T>())
|
||||
fun <T : AnyDiffRvItem> filterableListOf(scope: CoroutineScope) =
|
||||
FilterableDiffObservableList(DiffRvItem.callback<T>(), scope)
|
||||
|
@ -15,8 +15,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.BR
|
||||
|
||||
class RvItemAdapter<T: RvItem>(
|
||||
internal val items: List<T>,
|
||||
private val extraBindings: SparseArray<*>?
|
||||
val items: List<T>,
|
||||
val extraBindings: SparseArray<*>?
|
||||
) : RecyclerView.Adapter<RvItemAdapter.ViewHolder>() {
|
||||
|
||||
private var lifecycleOwner: LifecycleOwner? = null
|
||||
@ -113,7 +113,8 @@ inline fun bindExtra(body: (SparseArray<Any?>) -> Unit) = SparseArray<Any?>().al
|
||||
@BindingAdapter("items", "extraBindings", requireAll = false)
|
||||
fun <T: RvItem> RecyclerView.setAdapter(items: List<T>?, extraBindings: SparseArray<*>?) {
|
||||
if (items != null) {
|
||||
if ((adapter as? RvItemAdapter<T>)?.items !== items) {
|
||||
val rva = (adapter as? RvItemAdapter<*>)
|
||||
if (rva == null || rva.items !== items || rva.extraBindings !== extraBindings) {
|
||||
adapter = RvItemAdapter(items, extraBindings)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.deny
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
|
||||
import com.topjohnwu.magisk.core.di.AppContext
|
||||
@ -37,7 +38,7 @@ class DenyListViewModel : AsyncLoadViewModel() {
|
||||
query()
|
||||
}
|
||||
|
||||
val items = filterableListOf<DenyListRvItem>()
|
||||
val items = filterableListOf<DenyListRvItem>(viewModelScope)
|
||||
val extraBindings = bindExtra {
|
||||
it.put(BR.viewModel, this)
|
||||
}
|
||||
@ -68,7 +69,7 @@ class DenyListViewModel : AsyncLoadViewModel() {
|
||||
query()
|
||||
}
|
||||
|
||||
fun query() {
|
||||
private fun query() {
|
||||
items.filter {
|
||||
fun filterSystem() = isShowSystem || !it.info.isSystemApp()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user