mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-26 23:41:01 +00:00
Cleanup RvItems
This commit is contained in:
parent
f5c982355a
commit
067248da75
app/src/main/java/com/topjohnwu/magisk
arch
core/model/module
databinding
ui
flash
hide
log
module
settings
superuser
utils
view
@ -1,7 +1,8 @@
|
||||
package com.topjohnwu.magisk.arch
|
||||
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvItem
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
||||
@ -9,23 +10,14 @@ import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||
|
||||
fun <T : ComparableRvItem<*>> diffListOf(
|
||||
vararg newItems: T
|
||||
) = diffListOf(newItems.toList())
|
||||
fun <T : AnyDiffRvItem> diffListOf() =
|
||||
DiffObservableList(DiffRvItem.callback<T>())
|
||||
|
||||
fun <T : ComparableRvItem<*>> diffListOf(
|
||||
newItems: List<T>
|
||||
) = DiffObservableList(object : DiffObservableList.Callback<T> {
|
||||
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
||||
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
||||
}).also { it.update(newItems) }
|
||||
fun <T : AnyDiffRvItem> diffListOf(newItems: List<T>) =
|
||||
DiffObservableList(DiffRvItem.callback<T>()).also { it.update(newItems) }
|
||||
|
||||
fun <T : ComparableRvItem<*>> filterableListOf(
|
||||
vararg newItems: T
|
||||
) = FilterableDiffObservableList(object : DiffObservableList.Callback<T> {
|
||||
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
||||
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
||||
}).also { it.update(newItems.toList()) }
|
||||
fun <T : AnyDiffRvItem> filterableListOf() =
|
||||
FilterableDiffObservableList(DiffRvItem.callback<T>())
|
||||
|
||||
fun <T : RvItem> adapterOf() = object : BindingRecyclerViewAdapter<T>() {
|
||||
override fun onBindBinding(
|
||||
|
@ -7,13 +7,15 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
|
||||
class LocalModule(path: String) : Module() {
|
||||
override var id: String = ""
|
||||
override var name: String = ""
|
||||
override var author: String = ""
|
||||
override var version: String = ""
|
||||
override var versionCode: Int = -1
|
||||
override var description: String = ""
|
||||
data class LocalModule(
|
||||
private val path: String,
|
||||
override var id: String = "",
|
||||
override var name: String = "",
|
||||
override var author: String = "",
|
||||
override var version: String = "",
|
||||
override var versionCode: Int = -1,
|
||||
override var description: String = "",
|
||||
) : Module() {
|
||||
|
||||
private val removeFile = SuFile(path, "remove")
|
||||
private val disableFile = SuFile(path, "disable")
|
||||
|
@ -26,38 +26,57 @@ abstract class RvItem {
|
||||
open fun onBindingBound(binding: ViewDataBinding) {}
|
||||
}
|
||||
|
||||
abstract class ComparableRvItem<in T> : RvItem() {
|
||||
interface RvContainer<E> {
|
||||
val item: E
|
||||
}
|
||||
|
||||
// Use Any.equals by default
|
||||
open fun itemSameAs(other: T) = this == other
|
||||
|
||||
// Use compareTo if this is Comparable or assume not same
|
||||
interface ComparableRv<T> : Comparable<T> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun comparableEqual(o: Any?) =
|
||||
o != null && o::class == this::class && compareTo(o as T) == 0
|
||||
}
|
||||
|
||||
abstract class DiffRvItem<T> : RvItem() {
|
||||
|
||||
// Defer to contentSameAs by default
|
||||
open fun itemSameAs(other: T) = true
|
||||
|
||||
open fun contentSameAs(other: T) =
|
||||
(this as? Comparable<T>)?.run { compareTo(other) == 0 } ?: false
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open fun genericItemSameAs(other: Any): Boolean = other::class == this::class && itemSameAs(other as T)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open fun genericContentSameAs(other: Any): Boolean = other::class == this::class && contentSameAs(other as T)
|
||||
when (this) {
|
||||
is RvContainer<*> -> item == (other as RvContainer<*>).item
|
||||
is ComparableRv<*> -> comparableEqual(other)
|
||||
else -> this == other
|
||||
}
|
||||
|
||||
companion object {
|
||||
val callback = object : DiffObservableList.Callback<ComparableRvItem<*>> {
|
||||
private val callback = object : DiffObservableList.Callback<DiffRvItem<Any>> {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: ComparableRvItem<*>,
|
||||
newItem: ComparableRvItem<*>
|
||||
) = oldItem.genericItemSameAs(newItem)
|
||||
oldItem: DiffRvItem<Any>,
|
||||
newItem: DiffRvItem<Any>
|
||||
): Boolean {
|
||||
return oldItem::class == newItem::class && oldItem.itemSameAs(newItem)
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: ComparableRvItem<*>,
|
||||
newItem: ComparableRvItem<*>
|
||||
) = oldItem.genericContentSameAs(newItem)
|
||||
oldItem: DiffRvItem<Any>,
|
||||
newItem: DiffRvItem<Any>
|
||||
): Boolean {
|
||||
return oldItem.contentSameAs(newItem)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : AnyDiffRvItem> callback() = callback as DiffObservableList.Callback<T>
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ObservableItem<T> : ComparableRvItem<T>(), ObservableHost {
|
||||
typealias AnyDiffRvItem = DiffRvItem<*>
|
||||
|
||||
abstract class ObservableDiffRvItem<T> : DiffRvItem<T>(), ObservableHost {
|
||||
override var callbacks: PropertyChangeRegistry? = null
|
||||
}
|
||||
|
||||
abstract class ObservableRvItem : RvItem(), ObservableHost {
|
||||
override var callbacks: PropertyChangeRegistry? = null
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,15 @@ import androidx.core.view.updateLayoutParams
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.LenientRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvContainer
|
||||
import kotlin.math.max
|
||||
|
||||
class ConsoleItem(val item: String) : ComparableRvItem<ConsoleItem>(), LenientRvItem {
|
||||
class ConsoleItem(
|
||||
override val item: String
|
||||
) : DiffRvItem<ConsoleItem>(), LenientRvItem,
|
||||
RvContainer<String> {
|
||||
override val layoutRes = R.layout.item_console_md2
|
||||
|
||||
private var parentWidth = -1
|
||||
@ -31,7 +35,4 @@ class ConsoleItem(val item: String) : ComparableRvItem<ConsoleItem>(), LenientRv
|
||||
recyclerView.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
override fun contentSameAs(other: ConsoleItem) = itemSameAs(other)
|
||||
override fun itemSameAs(other: ConsoleItem) = item == other.item
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ import android.view.ViewGroup
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.databinding.ComparableRv
|
||||
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||
import com.topjohnwu.magisk.ktx.startAnimations
|
||||
import com.topjohnwu.magisk.utils.addOnPropertyChangedCallback
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
@ -14,7 +15,7 @@ import kotlin.math.roundToInt
|
||||
|
||||
class HideRvItem(
|
||||
val info: HideAppInfo
|
||||
) : ObservableItem<HideRvItem>(), Comparable<HideRvItem> {
|
||||
) : ObservableDiffRvItem<HideRvItem>(), ComparableRv<HideRvItem> {
|
||||
|
||||
override val layoutRes get() = R.layout.item_hide_md2
|
||||
|
||||
@ -89,7 +90,7 @@ class HideRvItem(
|
||||
|
||||
class HideProcessRvItem(
|
||||
val process: HideProcessInfo
|
||||
) : ObservableItem<HideProcessRvItem>() {
|
||||
) : ObservableDiffRvItem<HideProcessRvItem>() {
|
||||
|
||||
override val layoutRes get() = R.layout.item_hide_process_md2
|
||||
|
||||
|
@ -4,12 +4,15 @@ import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.model.su.SuLog
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvContainer
|
||||
import com.topjohnwu.magisk.ktx.timeDateFormat
|
||||
import com.topjohnwu.magisk.ktx.toTime
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
|
||||
class LogRvItem(val item: SuLog) : ObservableItem<LogRvItem>() {
|
||||
class LogRvItem(
|
||||
override val item: SuLog
|
||||
) : ObservableDiffRvItem<LogRvItem>(), RvContainer<SuLog> {
|
||||
|
||||
override val layoutRes = R.layout.item_log_access_md2
|
||||
|
||||
@ -24,14 +27,4 @@ class LogRvItem(val item: SuLog) : ObservableItem<LogRvItem>() {
|
||||
set(value) = set(value, field, { field = it }, BR.bottom)
|
||||
|
||||
override fun itemSameAs(other: LogRvItem) = item.appName == other.item.appName
|
||||
|
||||
override fun contentSameAs(other: LogRvItem) = item.fromUid == other.item.fromUid &&
|
||||
item.toUid == other.item.toUid &&
|
||||
item.fromPid == other.item.fromPid &&
|
||||
item.packageName == other.item.packageName &&
|
||||
item.command == other.item.command &&
|
||||
item.action == other.item.action &&
|
||||
item.time == other.item.time &&
|
||||
isTop == other.isTop &&
|
||||
isBottom == other.isBottom
|
||||
}
|
||||
|
@ -5,22 +5,20 @@ import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvContainer
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
|
||||
object InstallModule : ComparableRvItem<InstallModule>() {
|
||||
object InstallModule : DiffRvItem<InstallModule>() {
|
||||
override val layoutRes = R.layout.item_module_download
|
||||
|
||||
override fun contentSameAs(other: InstallModule) = this == other
|
||||
override fun itemSameAs(other: InstallModule) = this === other
|
||||
}
|
||||
|
||||
class SectionTitle(
|
||||
val title: Int,
|
||||
_button: Int = 0,
|
||||
_icon: Int = 0
|
||||
) : ObservableItem<SectionTitle>() {
|
||||
) : ObservableDiffRvItem<SectionTitle>() {
|
||||
override val layoutRes = R.layout.item_section_md2
|
||||
|
||||
@get:Bindable
|
||||
@ -34,12 +32,11 @@ class SectionTitle(
|
||||
@get:Bindable
|
||||
var hasButton = _button != 0 && _icon != 0
|
||||
set(value) = set(value, field, { field = it }, BR.hasButton)
|
||||
|
||||
override fun itemSameAs(other: SectionTitle): Boolean = this === other
|
||||
override fun contentSameAs(other: SectionTitle): Boolean = this === other
|
||||
}
|
||||
|
||||
class OnlineModuleRvItem(val item: OnlineModule) : ObservableItem<OnlineModuleRvItem>() {
|
||||
class OnlineModuleRvItem(
|
||||
override val item: OnlineModule
|
||||
) : ObservableDiffRvItem<OnlineModuleRvItem>(), RvContainer<OnlineModule> {
|
||||
override val layoutRes: Int = R.layout.item_repo_md2
|
||||
|
||||
@get:Bindable
|
||||
@ -48,12 +45,12 @@ class OnlineModuleRvItem(val item: OnlineModule) : ObservableItem<OnlineModuleRv
|
||||
|
||||
var hasUpdate = false
|
||||
|
||||
override fun contentSameAs(other: OnlineModuleRvItem): Boolean = item == other.item
|
||||
override fun itemSameAs(other: OnlineModuleRvItem): Boolean = item.id == other.item.id
|
||||
|
||||
}
|
||||
|
||||
class LocalModuleRvItem(val item: LocalModule) : ObservableItem<LocalModuleRvItem>() {
|
||||
class LocalModuleRvItem(
|
||||
override val item: LocalModule
|
||||
) : ObservableDiffRvItem<LocalModuleRvItem>(), RvContainer<LocalModule> {
|
||||
|
||||
override val layoutRes = R.layout.item_module_md2
|
||||
|
||||
@ -81,10 +78,5 @@ class LocalModuleRvItem(val item: LocalModule) : ObservableItem<LocalModuleRvIte
|
||||
viewModel.updateActiveState()
|
||||
}
|
||||
|
||||
override fun contentSameAs(other: LocalModuleRvItem): Boolean = item.version == other.item.version
|
||||
&& item.versionCode == other.item.versionCode
|
||||
&& item.description == other.item.description
|
||||
&& item.name == other.item.name
|
||||
|
||||
override fun itemSameAs(other: LocalModuleRvItem): Boolean = item.id == other.item.id
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import com.topjohnwu.magisk.arch.*
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvItem
|
||||
import com.topjohnwu.magisk.events.OpenReadmeEvent
|
||||
import com.topjohnwu.magisk.events.SelectModuleEvent
|
||||
@ -44,8 +44,8 @@ class ModuleViewModel : BaseViewModel(), Queryable {
|
||||
var searchLoading = false
|
||||
set(value) = set(value, field, { field = it }, BR.searchLoading)
|
||||
|
||||
val itemsSearch = diffListOf<ComparableRvItem<*>>()
|
||||
val itemSearchBinding = itemBindingOf<ComparableRvItem<*>> {
|
||||
val itemsSearch = diffListOf<AnyDiffRvItem>()
|
||||
val itemSearchBinding = itemBindingOf<AnyDiffRvItem> {
|
||||
it.bindExtra(BR.viewModel, this)
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ class ModuleViewModel : BaseViewModel(), Queryable {
|
||||
|
||||
// ---
|
||||
|
||||
private suspend fun queryInternal(query: String): List<ComparableRvItem<*>> {
|
||||
private suspend fun queryInternal(query: String): List<AnyDiffRvItem> {
|
||||
return if (query.isBlank()) {
|
||||
itemsSearch.clear()
|
||||
listOf()
|
||||
|
@ -7,12 +7,12 @@ import androidx.annotation.CallSuper
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableRvItem
|
||||
import com.topjohnwu.magisk.utils.TextHolder
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
|
||||
sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
||||
sealed class BaseSettingsItem : ObservableRvItem() {
|
||||
|
||||
override val layoutRes get() = R.layout.item_settings
|
||||
|
||||
@ -42,9 +42,6 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
||||
|
||||
open fun refresh() {}
|
||||
|
||||
override fun itemSameAs(other: BaseSettingsItem) = this === other
|
||||
override fun contentSameAs(other: BaseSettingsItem) = itemSameAs(other)
|
||||
|
||||
// ---
|
||||
|
||||
interface Callback {
|
||||
|
@ -10,7 +10,6 @@ import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.arch.adapterOf
|
||||
import com.topjohnwu.magisk.arch.diffListOf
|
||||
import com.topjohnwu.magisk.arch.itemBindingOf
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
@ -32,7 +31,7 @@ class SettingsViewModel(
|
||||
|
||||
val adapter = adapterOf<BaseSettingsItem>()
|
||||
val itemBinding = itemBindingOf<BaseSettingsItem> { it.bindExtra(BR.callback, this) }
|
||||
val items = diffListOf(createItems())
|
||||
val items = createItems()
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
|
@ -5,14 +5,15 @@ import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.databinding.ObservableItem
|
||||
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.RvContainer
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
|
||||
class PolicyRvItem(
|
||||
val item: SuPolicy,
|
||||
override val item: SuPolicy,
|
||||
val icon: Drawable,
|
||||
val viewModel: SuperuserViewModel
|
||||
) : ObservableItem<PolicyRvItem>() {
|
||||
) : ObservableDiffRvItem<PolicyRvItem>(), RvContainer<SuPolicy> {
|
||||
override val layoutRes = R.layout.item_policy_md2
|
||||
|
||||
@get:Bindable
|
||||
@ -64,7 +65,6 @@ class PolicyRvItem(
|
||||
viewModel.deletePressed(this)
|
||||
}
|
||||
|
||||
override fun contentSameAs(other: PolicyRvItem) = itemSameAs(other)
|
||||
override fun itemSameAs(other: PolicyRvItem) = item.uid == other.item.uid
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.events.dialog.BiometricEvent
|
||||
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
|
||||
@ -35,13 +35,13 @@ class SuperuserViewModel(
|
||||
private val itemsPolicies = diffListOf<PolicyRvItem>()
|
||||
private val itemsHelpers = ObservableArrayList<TextItem>()
|
||||
|
||||
val adapter = adapterOf<ComparableRvItem<*>>()
|
||||
val items = MergeObservableList<ComparableRvItem<*>>().apply {
|
||||
val adapter = adapterOf<AnyDiffRvItem>()
|
||||
val items = MergeObservableList<AnyDiffRvItem>().apply {
|
||||
if (Config.magiskHide)
|
||||
insertItem(TappableHeadlineItem.Hide)
|
||||
}.insertList(itemsHelpers)
|
||||
.insertList(itemsPolicies)
|
||||
val itemBinding = itemBindingOf<ComparableRvItem<*>> {
|
||||
val itemBinding = itemBindingOf<AnyDiffRvItem> {
|
||||
it.bindExtra(BR.listener, this)
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ class SuperuserViewModel(
|
||||
fun deletePressed(item: PolicyRvItem) {
|
||||
fun updateState() = viewModelScope.launch {
|
||||
db.delete(item.item.uid)
|
||||
itemsPolicies.removeAll { it.genericItemSameAs(item) }
|
||||
itemsPolicies.removeAll { it.itemSameAs(item) }
|
||||
if (itemsPolicies.isEmpty() && itemsHelpers.isEmpty()) {
|
||||
itemsHelpers.add(itemNoData)
|
||||
}
|
||||
|
@ -13,11 +13,10 @@ import kotlin.collections.ArrayList
|
||||
* @param detectMoves True if DiffUtil should try to detect moved items, false otherwise.
|
||||
*/
|
||||
open class DiffObservableList<T>(
|
||||
private val callback: Callback<T>,
|
||||
private val detectMoves: Boolean = true
|
||||
private val callback: Callback<T>,
|
||||
private val detectMoves: Boolean = true
|
||||
) : AbstractList<T>(), ObservableList<T> {
|
||||
|
||||
private val LIST_LOCK = Object()
|
||||
protected var list: MutableList<T> = ArrayList()
|
||||
private val listeners = ListChangeRegistry()
|
||||
protected val listCallback = ObservableListUpdateCallback()
|
||||
@ -32,27 +31,25 @@ open class DiffObservableList<T>(
|
||||
* list into the given one.
|
||||
*/
|
||||
fun calculateDiff(newItems: List<T>): DiffUtil.DiffResult {
|
||||
val frozenList = synchronized(LIST_LOCK) {
|
||||
ArrayList(list)
|
||||
}
|
||||
val frozenList = ArrayList(list)
|
||||
return doCalculateDiff(frozenList, newItems)
|
||||
}
|
||||
|
||||
protected fun doCalculateDiff(oldItems: List<T>, newItems: List<T>?): DiffUtil.DiffResult {
|
||||
protected fun doCalculateDiff(oldItems: List<T>, newItems: List<T>): DiffUtil.DiffResult {
|
||||
return DiffUtil.calculateDiff(object : DiffUtil.Callback() {
|
||||
override fun getOldListSize() = oldItems.size
|
||||
|
||||
override fun getNewListSize() = newItems?.size ?: 0
|
||||
override fun getNewListSize() = newItems.size
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldItems[oldItemPosition]
|
||||
val newItem = newItems!![newItemPosition]
|
||||
val newItem = newItems[newItemPosition]
|
||||
return callback.areItemsTheSame(oldItem, newItem)
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldItems[oldItemPosition]
|
||||
val newItem = newItems!![newItemPosition]
|
||||
val newItem = newItems[newItemPosition]
|
||||
return callback.areContentsTheSame(oldItem, newItem)
|
||||
}
|
||||
}, detectMoves)
|
||||
@ -67,9 +64,7 @@ open class DiffObservableList<T>(
|
||||
*/
|
||||
@MainThread
|
||||
fun update(newItems: List<T>, diffResult: DiffUtil.DiffResult) {
|
||||
synchronized(LIST_LOCK) {
|
||||
list = newItems.toMutableList()
|
||||
}
|
||||
list = newItems.toMutableList()
|
||||
diffResult.dispatchUpdatesTo(listCallback)
|
||||
}
|
||||
|
||||
@ -97,29 +92,14 @@ open class DiffObservableList<T>(
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
override fun get(index: Int): T {
|
||||
return list[index]
|
||||
}
|
||||
|
||||
override fun add(element: T): Boolean {
|
||||
list.add(element)
|
||||
notifyAdd(size - 1, 1)
|
||||
return true
|
||||
}
|
||||
override fun get(index: Int) = list[index]
|
||||
|
||||
override fun add(index: Int, element: T) {
|
||||
list.add(index, element)
|
||||
notifyAdd(index, 1)
|
||||
}
|
||||
|
||||
override fun addAll(elements: Collection<T>): Boolean {
|
||||
val oldSize = size
|
||||
val added = list.addAll(elements)
|
||||
if (added) {
|
||||
notifyAdd(oldSize, size - oldSize)
|
||||
}
|
||||
return added
|
||||
}
|
||||
override fun addAll(elements: Collection<T>) = addAll(size, elements)
|
||||
|
||||
override fun addAll(index: Int, elements: Collection<T>): Boolean {
|
||||
val added = list.addAll(index, elements)
|
||||
@ -153,14 +133,6 @@ open class DiffObservableList<T>(
|
||||
return element
|
||||
}
|
||||
|
||||
fun removeLast(): T? {
|
||||
if (size > 0) {
|
||||
val index = size - 1
|
||||
return removeAt(index)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun set(index: Int, element: T): T {
|
||||
val old = list.set(index, element)
|
||||
listeners.notifyChanged(this, index, 1)
|
||||
@ -228,6 +200,5 @@ open class DiffObservableList<T>(
|
||||
modCount += 1
|
||||
listeners.notifyRemoved(this@DiffObservableList, position, count)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,9 @@ import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.itemBindingOf
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
|
||||
import com.topjohnwu.magisk.databinding.RvContainer
|
||||
import com.topjohnwu.magisk.utils.ObservableHost
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
|
||||
@ -188,12 +189,10 @@ class MagiskDialog(
|
||||
}
|
||||
|
||||
class DialogItem(
|
||||
val item: CharSequence,
|
||||
override val item: CharSequence,
|
||||
val position: Int
|
||||
) : ComparableRvItem<DialogItem>() {
|
||||
) : DiffRvItem<DialogItem>(), RvContainer<CharSequence> {
|
||||
override val layoutRes = R.layout.item_list_single_line
|
||||
override fun itemSameAs(other: DialogItem) = item == other.item
|
||||
override fun contentSameAs(other: DialogItem) = itemSameAs(other)
|
||||
}
|
||||
|
||||
interface ActualOnDialogClickListener {
|
||||
|
@ -1,21 +1,15 @@
|
||||
package com.topjohnwu.magisk.view
|
||||
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
|
||||
sealed class TappableHeadlineItem : ComparableRvItem<TappableHeadlineItem>() {
|
||||
sealed class TappableHeadlineItem : DiffRvItem<TappableHeadlineItem>() {
|
||||
|
||||
abstract val title: Int
|
||||
abstract val icon: Int
|
||||
|
||||
override val layoutRes = R.layout.item_tappable_headline
|
||||
|
||||
override fun itemSameAs(other: TappableHeadlineItem) =
|
||||
this === other
|
||||
|
||||
override fun contentSameAs(other: TappableHeadlineItem) =
|
||||
title == other.title && icon == other.icon
|
||||
|
||||
// --- listener
|
||||
|
||||
interface Listener {
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.topjohnwu.magisk.view
|
||||
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.databinding.DiffRvItem
|
||||
|
||||
class TextItem(val text: Int) : ComparableRvItem<TextItem>() {
|
||||
class TextItem(val text: Int) : DiffRvItem<TextItem>() {
|
||||
override val layoutRes = R.layout.item_text
|
||||
|
||||
override fun contentSameAs(other: TextItem) = text == other.text
|
||||
override fun itemSameAs(other: TextItem) = contentSameAs(other)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user