mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Remove usage of BindingCollectionAdapter (part 2)
This commit is contained in:
parent
6305159c5e
commit
5471147422
@ -78,10 +78,6 @@ dependencies {
|
|||||||
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.1")
|
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.1")
|
||||||
implementation("io.noties.markwon:core:4.6.2")
|
implementation("io.noties.markwon:core:4.6.2")
|
||||||
|
|
||||||
val vBAdapt = "4.0.0"
|
|
||||||
val bindingAdapter = "me.tatarka.bindingcollectionadapter2:bindingcollectionadapter"
|
|
||||||
implementation("${bindingAdapter}:${vBAdapt}")
|
|
||||||
|
|
||||||
val vLibsu = "5.0.2"
|
val vLibsu = "5.0.2"
|
||||||
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
|
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
|
||||||
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
|
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
|
||||||
|
@ -8,10 +8,7 @@ import android.text.Spanned
|
|||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.*
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.ProgressBar
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
@ -295,3 +292,8 @@ fun TextView.setTextColorAttr(attr: Int) {
|
|||||||
fun TextView.setText(text: TextHolder) {
|
fun TextView.setText(text: TextHolder) {
|
||||||
this.text = text.getText(context.resources)
|
this.text = text.getText(context.resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("items", "layout")
|
||||||
|
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
|
||||||
|
adapter = ArrayAdapter(context, layoutRes, items)
|
||||||
|
}
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
package com.topjohnwu.magisk.databinding
|
||||||
|
|
||||||
|
import androidx.databinding.ListChangeRegistry
|
||||||
|
import androidx.databinding.ObservableList
|
||||||
|
import androidx.databinding.ObservableList.OnListChangedCallback
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class MergeObservableList<T> : AbstractList<T>(), ObservableList<T> {
|
||||||
|
|
||||||
|
private val lists: MutableList<List<T>> = mutableListOf()
|
||||||
|
private val listeners = ListChangeRegistry()
|
||||||
|
private val callback = Callback<T>()
|
||||||
|
|
||||||
|
override fun addOnListChangedCallback(callback: OnListChangedCallback<out ObservableList<T>>) {
|
||||||
|
listeners.add(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeOnListChangedCallback(callback: OnListChangedCallback<out ObservableList<T>>) {
|
||||||
|
listeners.remove(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(index: Int): T {
|
||||||
|
if (index < 0)
|
||||||
|
throw IndexOutOfBoundsException()
|
||||||
|
var idx = index
|
||||||
|
for (list in lists) {
|
||||||
|
val size = list.size
|
||||||
|
if (idx < size) {
|
||||||
|
return list[idx]
|
||||||
|
}
|
||||||
|
idx -= size
|
||||||
|
}
|
||||||
|
throw IndexOutOfBoundsException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = lists.fold(0) { i, it -> i + it.size }
|
||||||
|
|
||||||
|
|
||||||
|
fun insertItem(obj: T): MergeObservableList<T> {
|
||||||
|
val idx = size
|
||||||
|
lists.add(listOf(obj))
|
||||||
|
++modCount
|
||||||
|
listeners.notifyInserted(this, idx, 1)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun insertList(list: ObservableList<out T>): MergeObservableList<T> {
|
||||||
|
val idx = size
|
||||||
|
lists.add(list)
|
||||||
|
++modCount
|
||||||
|
(list as ObservableList<T>).addOnListChangedCallback(callback)
|
||||||
|
if (list.isNotEmpty())
|
||||||
|
listeners.notifyInserted(this, idx, list.size)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeItem(obj: T): Boolean {
|
||||||
|
var idx = 0
|
||||||
|
for ((i, list) in lists.withIndex()) {
|
||||||
|
if (list !is ObservableList<*>) {
|
||||||
|
if (obj == list[0]) {
|
||||||
|
lists.removeAt(i)
|
||||||
|
++modCount
|
||||||
|
listeners.notifyRemoved(this, idx, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx += list.size
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeList(listToRemove: ObservableList<out T>): Boolean {
|
||||||
|
var idx = 0
|
||||||
|
for ((i, list) in lists.withIndex()) {
|
||||||
|
if (listToRemove === list) {
|
||||||
|
(list as ObservableList<T>).removeOnListChangedCallback(callback)
|
||||||
|
lists.removeAt(i)
|
||||||
|
++modCount
|
||||||
|
listeners.notifyRemoved(this, idx, list.size)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
idx += list.size
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear() {
|
||||||
|
val sz = size
|
||||||
|
for (list in lists) {
|
||||||
|
if (list is ObservableList<*>) {
|
||||||
|
(list as ObservableList<T>).removeOnListChangedCallback(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++modCount
|
||||||
|
lists.clear()
|
||||||
|
if (sz > 0)
|
||||||
|
listeners.notifyRemoved(this, 0, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subIndexToIndex(subList: List<*>, index: Int): Int {
|
||||||
|
if (index < 0)
|
||||||
|
throw IndexOutOfBoundsException()
|
||||||
|
var idx = 0
|
||||||
|
for (list in lists) {
|
||||||
|
if (subList === list) {
|
||||||
|
return idx + index
|
||||||
|
}
|
||||||
|
idx += list.size
|
||||||
|
}
|
||||||
|
throw IllegalArgumentException()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class Callback<T> : OnListChangedCallback<ObservableList<T>>() {
|
||||||
|
override fun onChanged(sender: ObservableList<T>) {
|
||||||
|
++modCount
|
||||||
|
listeners.notifyChanged(this@MergeObservableList)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeChanged(
|
||||||
|
sender: ObservableList<T>,
|
||||||
|
positionStart: Int,
|
||||||
|
itemCount: Int
|
||||||
|
) {
|
||||||
|
listeners.notifyChanged(this@MergeObservableList,
|
||||||
|
subIndexToIndex(sender, positionStart), itemCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeInserted(
|
||||||
|
sender: ObservableList<T>,
|
||||||
|
positionStart: Int,
|
||||||
|
itemCount: Int
|
||||||
|
) {
|
||||||
|
++modCount
|
||||||
|
listeners.notifyInserted(this@MergeObservableList,
|
||||||
|
subIndexToIndex(sender, positionStart), itemCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeMoved(
|
||||||
|
sender: ObservableList<T>,
|
||||||
|
fromPosition: Int,
|
||||||
|
toPosition: Int,
|
||||||
|
itemCount: Int
|
||||||
|
) {
|
||||||
|
val idx = subIndexToIndex(sender, 0)
|
||||||
|
listeners.notifyMoved(this@MergeObservableList,
|
||||||
|
idx + fromPosition, idx + toPosition, itemCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeRemoved(
|
||||||
|
sender: ObservableList<T>,
|
||||||
|
positionStart: Int,
|
||||||
|
itemCount: Int
|
||||||
|
) {
|
||||||
|
++modCount
|
||||||
|
listeners.notifyRemoved(this@MergeObservableList,
|
||||||
|
subIndexToIndex(sender, positionStart), itemCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.*
|
import com.topjohnwu.magisk.arch.*
|
||||||
@ -23,7 +24,6 @@ import com.topjohnwu.magisk.utils.Utils
|
|||||||
import com.topjohnwu.magisk.utils.asText
|
import com.topjohnwu.magisk.utils.asText
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import me.tatarka.bindingcollectionadapter2.BR
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
enum class MagiskState {
|
enum class MagiskState {
|
||||||
|
@ -10,6 +10,7 @@ import com.topjohnwu.magisk.core.Info
|
|||||||
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
||||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||||
|
import com.topjohnwu.magisk.databinding.MergeObservableList
|
||||||
import com.topjohnwu.magisk.databinding.RvItem
|
import com.topjohnwu.magisk.databinding.RvItem
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
import com.topjohnwu.magisk.databinding.bindExtra
|
||||||
import com.topjohnwu.magisk.databinding.diffListOf
|
import com.topjohnwu.magisk.databinding.diffListOf
|
||||||
@ -21,7 +22,6 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList
|
|
||||||
|
|
||||||
class ModuleViewModel : BaseViewModel() {
|
class ModuleViewModel : BaseViewModel() {
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import com.topjohnwu.magisk.core.model.su.SuPolicy
|
|||||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
||||||
|
import com.topjohnwu.magisk.databinding.MergeObservableList
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
import com.topjohnwu.magisk.databinding.bindExtra
|
||||||
import com.topjohnwu.magisk.databinding.diffListOf
|
import com.topjohnwu.magisk.databinding.diffListOf
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
@ -27,7 +28,6 @@ import com.topjohnwu.magisk.view.TextItem
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList
|
|
||||||
|
|
||||||
class SuperuserViewModel(
|
class SuperuserViewModel(
|
||||||
private val db: PolicyDao
|
private val db: PolicyDao
|
||||||
|
@ -34,7 +34,6 @@ import com.topjohnwu.magisk.ktx.getLabel
|
|||||||
import com.topjohnwu.magisk.utils.TextHolder
|
import com.topjohnwu.magisk.utils.TextHolder
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
|
||||||
import java.util.concurrent.TimeUnit.SECONDS
|
import java.util.concurrent.TimeUnit.SECONDS
|
||||||
|
|
||||||
class SuRequestViewModel(
|
class SuRequestViewModel(
|
||||||
@ -70,8 +69,6 @@ class SuRequestViewModel(
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
val itemBinding = ItemBinding.of<String>(BR.item, R.layout.item_spinner)
|
|
||||||
|
|
||||||
private val handler = SuRequestHandler(AppContext.packageManager, policyDB)
|
private val handler = SuRequestHandler(AppContext.packageManager, policyDB)
|
||||||
private lateinit var timer: CountDownTimer
|
private lateinit var timer: CountDownTimer
|
||||||
private var initialized = false
|
private var initialized = false
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<import type="java.util.Arrays"/>
|
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="com.topjohnwu.magisk.ui.surequest.SuRequestViewModel" />
|
type="com.topjohnwu.magisk.ui.surequest.SuRequestViewModel" />
|
||||||
@ -101,8 +99,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:enabled="@{viewModel.grantEnabled}"
|
android:enabled="@{viewModel.grantEnabled}"
|
||||||
app:items="@{Arrays.asList(@stringArray/allow_timeout)}"
|
app:items="@{@stringArray/allow_timeout}"
|
||||||
app:itemBinding="@{viewModel.itemBinding}"
|
app:layout="@{@layout/item_spinner}"
|
||||||
android:selection="@={viewModel.selectedItemPosition}" />
|
android:selection="@={viewModel.selectedItemPosition}" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -1,25 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="?android:attr/spinnerItemStyle"
|
||||||
<data>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
<variable name="item" type="String" />
|
android:ellipsize="marquee"
|
||||||
|
android:background="?colorSurfaceSurfaceVariant"
|
||||||
</data>
|
android:textAppearance="@style/AppearanceFoundation.Caption"
|
||||||
|
android:gravity="center_vertical"
|
||||||
<TextView
|
android:minHeight="?attr/listPreferredItemHeightSmall"
|
||||||
style="?android:attr/spinnerItemStyle"
|
android:singleLine="true"
|
||||||
android:layout_width="match_parent"
|
android:textAlignment="inherit"
|
||||||
android:layout_height="wrap_content"
|
tools:text="Forever" />
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:background="?colorSurfaceSurfaceVariant"
|
|
||||||
android:textAppearance="@style/AppearanceFoundation.Caption"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:minHeight="?attr/listPreferredItemHeightSmall"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@{item}"
|
|
||||||
android:textAlignment="inherit"
|
|
||||||
tools:text="Forever" />
|
|
||||||
|
|
||||||
</layout>
|
|
||||||
|
Loading…
Reference in New Issue
Block a user