You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Replaced xml navigation with self-handled
This commit is contained in:
@@ -3,23 +3,42 @@ package com.topjohnwu.magisk.ui
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.topjohnwu.magisk.ClassMap
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ActivityMainBinding
|
||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.ui.hide.MagiskHideFragment
|
||||
import com.topjohnwu.magisk.ui.log.LogFragment
|
||||
import com.topjohnwu.magisk.ui.module.ModulesFragment
|
||||
import com.topjohnwu.magisk.ui.module.ReposFragment
|
||||
import com.topjohnwu.magisk.ui.settings.SettingsFragment
|
||||
import com.topjohnwu.magisk.ui.superuser.SuperuserFragment
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.net.Networking
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import kotlin.reflect.KClass
|
||||
import com.topjohnwu.magisk.ui.home.MagiskFragment as HomeFragment
|
||||
|
||||
open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
|
||||
override val layoutRes: Int = R.layout.activity_main
|
||||
override val viewModel: MainViewModel by viewModel()
|
||||
override val navHostId: Int = R.id.main_nav_host
|
||||
override val defaultPosition: Int = 0
|
||||
|
||||
override val baseFragments: List<KClass<out Fragment>> = listOf(
|
||||
HomeFragment::class,
|
||||
SuperuserFragment::class,
|
||||
MagiskHideFragment::class,
|
||||
ModulesFragment::class,
|
||||
ReposFragment::class,
|
||||
LogFragment::class,
|
||||
SettingsFragment::class
|
||||
)
|
||||
|
||||
/*override fun getDarkTheme(): Int {
|
||||
return R.style.AppTheme_Dark
|
||||
@@ -35,7 +54,6 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
checkHideSection()
|
||||
setSupportActionBar(binding.mainInclude.mainToolbar)
|
||||
|
||||
binding.navView.setupWithNavController(navController)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.topjohnwu.magisk.ui
|
||||
|
||||
import android.view.MenuItem
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
|
||||
@@ -8,4 +10,18 @@ class MainViewModel : MagiskViewModel() {
|
||||
|
||||
fun navPressed() = Navigation.Main.OPEN_NAV.publish()
|
||||
|
||||
fun navigationItemPressed(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.magiskFragment -> Navigation.home()
|
||||
R.id.superuserFragment -> Navigation.superuser()
|
||||
R.id.magiskHideFragment -> Navigation.hide()
|
||||
R.id.modulesFragment -> Navigation.modules()
|
||||
R.id.reposFragment -> Navigation.repos()
|
||||
R.id.logFragment -> Navigation.log()
|
||||
R.id.settings -> Navigation.settings()
|
||||
else -> null
|
||||
}?.publish()?.let { return@navigationItemPressed true }
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,126 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.core.net.toUri
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.ncapdevi.fragnav.FragNavController
|
||||
import com.ncapdevi.fragnav.FragNavTransactionOptions
|
||||
import com.skoumal.teanity.viewevents.ViewEvent
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
||||
import com.topjohnwu.magisk.model.navigation.Navigator
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import timber.log.Timber
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
MagiskLeanbackActivity<ViewModel, Binding>() {
|
||||
MagiskLeanbackActivity<ViewModel, Binding>(), FragNavController.RootFragmentListener,
|
||||
Navigator {
|
||||
|
||||
override val numberOfRootFragments: Int get() = baseFragments.size
|
||||
override val baseFragments: List<KClass<out Fragment>> = listOf()
|
||||
|
||||
protected open val defaultPosition: Int = 0
|
||||
|
||||
protected val navigationController by lazy {
|
||||
if (navHostId == 0) throw IllegalStateException("Did you forget to override \"navHostId\"?")
|
||||
FragNavController(supportFragmentManager, navHostId)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
navigationController.apply {
|
||||
rootFragmentListener = this@MagiskActivity
|
||||
initialize(defaultPosition, savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
navigationController.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is MagiskNavigationEvent -> navigateTo(event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRootFragment(index: Int) = baseFragments[index].java.newInstance()
|
||||
|
||||
override fun navigateTo(event: MagiskNavigationEvent) {
|
||||
val directions = event.navDirections
|
||||
|
||||
navigationController.defaultTransactionOptions = FragNavTransactionOptions.newBuilder()
|
||||
.customAnimations(event.animOptions)
|
||||
.build()
|
||||
|
||||
navigationController.currentStack
|
||||
?.indexOfFirst { it.javaClass == event.navOptions.popUpTo }
|
||||
?.let { if (it == -1) null else it } // invalidate if class is not found
|
||||
?.let { if (event.navOptions.inclusive) it + 1 else it }
|
||||
?.let { navigationController.popFragments(it) }
|
||||
|
||||
when (directions.isActivity) {
|
||||
true -> navigateToActivity(event)
|
||||
else -> navigateToFragment(event)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToActivity(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
val options = event.navOptions
|
||||
|
||||
Intent(this, destination)
|
||||
.putExtras(event.navDirections.args)
|
||||
.apply {
|
||||
if (options.singleTop) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
if (options.clearTask) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
}
|
||||
.let { startActivity(it) }
|
||||
}
|
||||
|
||||
private fun navigateToFragment(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
|
||||
when (val index = baseFragments.indexOfFirst { it.java.name == destination.name }) {
|
||||
-1 -> destination.newInstance()
|
||||
.apply { arguments = event.navDirections.args }
|
||||
.let { navigationController.pushFragment(it) }
|
||||
// When it's desired that fragments of same class are put on top of one another edit this
|
||||
else -> navigationController.switchTab(index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
val fragment = navigationController.currentFrag as? MagiskFragment<*, *>
|
||||
|
||||
if (fragment?.onBackPressed() == true) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
navigationController.popFragment()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
fun openUrl(url: String) = Utils.openLink(this, url.toUri())
|
||||
|
||||
private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) =
|
||||
customAnimations(options.enter, options.exit, options.popEnter, options.popExit)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,35 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.skoumal.teanity.view.TeanityFragment
|
||||
import com.skoumal.teanity.viewevents.ViewEvent
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
||||
import com.topjohnwu.magisk.model.navigation.Navigator
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
abstract class MagiskFragment<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
TeanityFragment<ViewModel, Binding>() {
|
||||
TeanityFragment<ViewModel, Binding>(), Navigator {
|
||||
|
||||
protected val magiskActivity get() = activity as MagiskActivity<*, *>
|
||||
|
||||
fun openLink(url: String) {
|
||||
magiskActivity.openUrl(url)
|
||||
// We don't need nested fragments
|
||||
override val baseFragments: List<KClass<Fragment>> = listOf()
|
||||
|
||||
override fun navigateTo(event: MagiskNavigationEvent) = magiskActivity.navigateTo(event)
|
||||
|
||||
@CallSuper
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is MagiskNavigationEvent -> navigateTo(event)
|
||||
}
|
||||
}
|
||||
|
||||
fun openLink(url: String) = magiskActivity.openUrl(url)
|
||||
|
||||
open fun onBackPressed(): Boolean = false
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user