Tidy up ViewEvents
This commit is contained in:
parent
a86d5b3e61
commit
d7a26dbf27
@ -8,6 +8,8 @@ import androidx.navigation.NavDirections
|
|||||||
import com.topjohnwu.magisk.MainDirections
|
import com.topjohnwu.magisk.MainDirections
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
class InstallExternalModuleEvent : ViewEvent(), ActivityExecutor {
|
class InstallExternalModuleEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import androidx.annotation.AttrRes
|
|||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.ui.base.ContextExecutor
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
data class OpenInappLinkEvent(
|
data class OpenInappLinkEvent(
|
||||||
private val link: String
|
private val link: String
|
||||||
|
@ -5,7 +5,9 @@ import androidx.annotation.StringRes
|
|||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.ktx.snackbar
|
import com.topjohnwu.magisk.ktx.snackbar
|
||||||
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
class SnackbarEvent private constructor(
|
class SnackbarEvent private constructor(
|
||||||
@StringRes private val messageRes: Int,
|
@StringRes private val messageRes: Int,
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
|
||||||
|
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observer for [ViewEvent]s, which automatically checks if event was handled
|
|
||||||
*/
|
|
||||||
class ViewEventObserver(private val onEventUnhandled: (ViewEvent) -> Unit) : Observer<ViewEvent> {
|
|
||||||
override fun onChanged(event: ViewEvent?) {
|
|
||||||
event?.let {
|
|
||||||
if (!it.handled) {
|
|
||||||
it.handled = true
|
|
||||||
onEventUnhandled(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package com.topjohnwu.magisk.model.events
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
@ -12,12 +11,19 @@ import com.topjohnwu.magisk.core.utils.SafetyNetHelper
|
|||||||
import com.topjohnwu.magisk.data.network.GithubRawServices
|
import com.topjohnwu.magisk.data.network.GithubRawServices
|
||||||
import com.topjohnwu.magisk.ktx.DynamicClassLoader
|
import com.topjohnwu.magisk.ktx.DynamicClassLoader
|
||||||
import com.topjohnwu.magisk.ktx.writeTo
|
import com.topjohnwu.magisk.ktx.writeTo
|
||||||
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.ui.base.ContextExecutor
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEventWithScope
|
||||||
import com.topjohnwu.magisk.ui.safetynet.SafetyNetResult
|
import com.topjohnwu.magisk.ui.safetynet.SafetyNetResult
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import dalvik.system.DexFile
|
import dalvik.system.DexFile
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CancellationException
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
import org.koin.core.inject
|
import org.koin.core.inject
|
||||||
@ -26,35 +32,9 @@ import java.io.File
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.reflect.InvocationHandler
|
import java.lang.reflect.InvocationHandler
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for passing events from ViewModels to Activities/Fragments
|
|
||||||
* Variable [handled] used so each event is handled only once
|
|
||||||
* (see https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150)
|
|
||||||
* Use [ViewEventObserver] for observing these events
|
|
||||||
*/
|
|
||||||
abstract class ViewEvent {
|
|
||||||
var handled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ViewEventsWithScope: ViewEvent() {
|
|
||||||
lateinit var scope: CoroutineScope
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ContextExecutor {
|
|
||||||
operator fun invoke(context: Context)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ActivityExecutor {
|
|
||||||
operator fun invoke(activity: BaseActivity)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FragmentExecutor {
|
|
||||||
operator fun invoke(fragment: Fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
class CheckSafetyNetEvent(
|
class CheckSafetyNetEvent(
|
||||||
private val callback: (SafetyNetResult) -> Unit = {}
|
private val callback: (SafetyNetResult) -> Unit = {}
|
||||||
) : ViewEventsWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
) : ViewEventWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
||||||
|
|
||||||
private val svc by inject<GithubRawServices>()
|
private val svc by inject<GithubRawServices>()
|
||||||
|
|
||||||
@ -161,7 +141,7 @@ class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), Activi
|
|||||||
override fun invoke(activity: BaseActivity) = action(activity)
|
override fun invoke(activity: BaseActivity) = action(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpenChangelogEvent(val item: Repo) : ViewEventsWithScope(), ContextExecutor {
|
class OpenChangelogEvent(val item: Repo) : ViewEventWithScope(), ContextExecutor {
|
||||||
override fun invoke(context: Context) {
|
override fun invoke(context: Context) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
MarkDownWindow.show(context, null, item::readme)
|
MarkDownWindow.show(context, null, item::readme)
|
||||||
|
@ -2,8 +2,8 @@ package com.topjohnwu.magisk.model.events.dialog
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
class BiometricDialog(
|
class BiometricDialog(
|
||||||
builder: Builder.() -> Unit
|
builder: Builder.() -> Unit
|
||||||
|
@ -5,7 +5,7 @@ import androidx.appcompat.app.AppCompatDelegate
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.topjohnwu.magisk.model.events.dialog
|
package com.topjohnwu.magisk.model.events.dialog
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.topjohnwu.magisk.model.events.ContextExecutor
|
import com.topjohnwu.magisk.ui.base.ContextExecutor
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
|
|
||||||
abstract class DialogEvent : ViewEvent(), ContextExecutor {
|
abstract class DialogEvent : ViewEvent(), ContextExecutor {
|
||||||
|
@ -2,9 +2,9 @@ package com.topjohnwu.magisk.model.navigation
|
|||||||
|
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
class NavigationWrapper(
|
class NavigationWrapper(
|
||||||
private val directions: NavDirections
|
private val directions: NavDirections
|
||||||
|
@ -17,9 +17,6 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ContextExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ui.theme.Theme
|
import com.topjohnwu.magisk.ui.theme.Theme
|
||||||
|
|
||||||
abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
|
abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||||
@ -94,9 +91,10 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
|
|||||||
return currentFragment?.onKeyEvent(event) == true || super.dispatchKeyEvent(event)
|
return currentFragment?.onKeyEvent(event) == true || super.dispatchKeyEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) = when(event) {
|
||||||
(event as? ContextExecutor)?.invoke(this)
|
is ContextExecutor -> event(this)
|
||||||
(event as? ActivityExecutor)?.invoke(this)
|
is ActivityExecutor -> event(this)
|
||||||
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
|
@ -5,7 +5,6 @@ import androidx.core.graphics.Insets
|
|||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
|
|
||||||
interface BaseUIComponent<VM : BaseViewModel>: LifecycleOwner {
|
interface BaseUIComponent<VM : BaseViewModel>: LifecycleOwner {
|
||||||
|
|
||||||
|
@ -13,10 +13,6 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ContextExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.FragmentExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
|
|
||||||
abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
|
abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||||
Fragment(), BaseUIComponent<VM> {
|
Fragment(), BaseUIComponent<VM> {
|
||||||
@ -47,10 +43,11 @@ abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
|
|||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) = when(event) {
|
||||||
(event as? ContextExecutor)?.invoke(requireContext())
|
is ContextExecutor -> event(requireContext())
|
||||||
(event as? FragmentExecutor)?.invoke(this)
|
is ActivityExecutor -> event(activity)
|
||||||
(event as? ActivityExecutor)?.invoke(activity)
|
is FragmentExecutor -> event(this)
|
||||||
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun onKeyEvent(event: KeyEvent): Boolean {
|
open fun onKeyEvent(event: KeyEvent): Boolean {
|
||||||
|
@ -15,7 +15,10 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.model.events.*
|
import com.topjohnwu.magisk.model.events.BackPressEvent
|
||||||
|
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||||
|
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||||
|
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||||
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
||||||
import com.topjohnwu.magisk.utils.ObservableHost
|
import com.topjohnwu.magisk.utils.ObservableHost
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
@ -102,7 +105,7 @@ abstract class BaseViewModel(
|
|||||||
_viewEvents.postValue(this)
|
_viewEvents.postValue(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <Event : ViewEventsWithScope> Event.publish() {
|
fun <Event : ViewEventWithScope> Event.publish() {
|
||||||
scope = viewModelScope
|
scope = viewModelScope
|
||||||
_viewEvents.postValue(this)
|
_viewEvents.postValue(this)
|
||||||
}
|
}
|
||||||
|
28
app/src/main/java/com/topjohnwu/magisk/ui/base/ViewEvent.kt
Normal file
28
app/src/main/java/com/topjohnwu/magisk/ui/base/ViewEvent.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.base
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for passing events from ViewModels to Activities/Fragments
|
||||||
|
* (see https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150)
|
||||||
|
*/
|
||||||
|
abstract class ViewEvent
|
||||||
|
|
||||||
|
abstract class ViewEventWithScope: ViewEvent() {
|
||||||
|
lateinit var scope: CoroutineScope
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContextExecutor {
|
||||||
|
operator fun invoke(context: Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActivityExecutor {
|
||||||
|
operator fun invoke(activity: BaseActivity)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FragmentExecutor {
|
||||||
|
operator fun invoke(fragment: Fragment)
|
||||||
|
}
|
@ -17,13 +17,13 @@ import com.topjohnwu.magisk.ktx.packageName
|
|||||||
import com.topjohnwu.magisk.ktx.res
|
import com.topjohnwu.magisk.ktx.res
|
||||||
import com.topjohnwu.magisk.model.entity.IconLink
|
import com.topjohnwu.magisk.model.entity.IconLink
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
|
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
|
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
||||||
|
import com.topjohnwu.magisk.ui.base.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -12,10 +12,10 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||||
import com.topjohnwu.magisk.ktx.hideKeyboard
|
import com.topjohnwu.magisk.ktx.hideKeyboard
|
||||||
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ui.MainActivity
|
import com.topjohnwu.magisk.ui.MainActivity
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIFragment
|
import com.topjohnwu.magisk.ui.base.BaseUIFragment
|
||||||
import com.topjohnwu.magisk.ui.base.ReselectionTarget
|
import com.topjohnwu.magisk.ui.base.ReselectionTarget
|
||||||
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||||
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
@ -4,7 +4,7 @@ import androidx.recyclerview.widget.GridLayoutManager
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.ui.base.ViewEvent
|
||||||
|
|
||||||
class EndlessRecyclerScrollListener(
|
class EndlessRecyclerScrollListener(
|
||||||
private val layoutManager: RecyclerView.LayoutManager,
|
private val layoutManager: RecyclerView.LayoutManager,
|
||||||
|
Loading…
Reference in New Issue
Block a user