add transition animation for NavHost

This commit is contained in:
BinTianqi
2024-03-03 17:25:39 +08:00
parent 2582116a9d
commit 0cc3b66b79
11 changed files with 83 additions and 14 deletions

View File

@@ -77,7 +77,7 @@ fun ApplicationManage(){
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()})
) )
} }
Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
if(isWear){ if(isWear){
TextField( TextField(
value = pkgName, value = pkgName,

View File

@@ -48,7 +48,7 @@ fun SystemManage(){
val userManager = myContext.getSystemService(Context.USER_SERVICE) as UserManager val userManager = myContext.getSystemService(Context.USER_SERVICE) as UserManager
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge} val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
Column(modifier = Modifier.verticalScroll(rememberScrollState()).navigationBarsPadding()) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
if(isDeviceOwner(myDpm)||isProfileOwner(myDpm)){ if(isDeviceOwner(myDpm)||isProfileOwner(myDpm)){
DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0, DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0,
{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)} {myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)}

View File

@@ -15,11 +15,13 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.outlined.Home import androidx.compose.material.icons.outlined.Home
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.MaterialTheme.typography
@@ -40,6 +42,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
import com.binbin.androidowner.ui.theme.Animations
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
@@ -121,14 +124,18 @@ fun MyScaffold(){
topBar = { topBar = {
if(!sharedPref.getBoolean("isWear",false)){ if(!sharedPref.getBoolean("isWear",false)){
TopAppBar( TopAppBar(
title = { Text(text = stringResource(topBarName) , color = MaterialTheme.colorScheme.onSurface) }, title = {Text(text = stringResource(topBarName) , color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.padding(bottom = 2.dp))},
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface containerColor = MaterialTheme.colorScheme.surface
), ),
navigationIcon = { navigationIcon = {
if(topBarName!=R.string.app_name){ AnimatedVisibility(
visible = topBarName!=R.string.app_name,
enter = Animations(myContext).navIconEnterTransition,
exit = Animations(myContext).navIconExitTransition
){
Icon( Icon(
imageVector = Icons.Outlined.ArrowBack, imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = "Back", contentDescription = "Back",
modifier = Modifier modifier = Modifier
.padding(horizontal = 6.dp) .padding(horizontal = 6.dp)
@@ -163,7 +170,11 @@ fun MyScaffold(){
NavHost( NavHost(
navController = navCtrl, navController = navCtrl,
startDestination = "HomePage", startDestination = "HomePage",
modifier = Modifier.padding(top = it.calculateTopPadding()).imePadding() modifier = Modifier.fillMaxSize().padding(top = it.calculateTopPadding()).imePadding(),
enterTransition = Animations(myContext).navHostEnterTransition,
exitTransition = Animations(myContext).navHostExitTransition,
popEnterTransition = Animations(myContext).navHostPopEnterTransition,
popExitTransition = Animations(myContext).navHostPopExitTransition
){ ){
composable(route = "HomePage", content = { HomePage(navCtrl)}) composable(route = "HomePage", content = { HomePage(navCtrl)})
composable(route = "DeviceControl", content = { SystemManage()}) composable(route = "DeviceControl", content = { SystemManage()})

View File

@@ -43,7 +43,7 @@ fun ManagedProfile() {
val isWear = sharedPref.getBoolean("isWear",false) val isWear = sharedPref.getBoolean("isWear",false)
val bodyTextStyle = if(isWear){ typography.bodyMedium}else{ typography.bodyLarge} val bodyTextStyle = if(isWear){ typography.bodyMedium}else{ typography.bodyLarge}
val titleColor = colorScheme.onPrimaryContainer val titleColor = colorScheme.onPrimaryContainer
Column(modifier = Modifier.verticalScroll(rememberScrollState())){ Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = stringResource(R.string.info), style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.info), style = typography.titleLarge, color = titleColor)

View File

@@ -46,7 +46,7 @@ import androidx.core.net.toUri
var ssidSet = mutableSetOf<WifiSsid>() var ssidSet = mutableSetOf<WifiSsid>()
@Composable @Composable
fun Network(){ fun Network(){
Column(modifier = Modifier.verticalScroll(rememberScrollState()).fillMaxWidth()){ Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){
val myContext = LocalContext.current val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java) val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)

View File

@@ -48,7 +48,7 @@ fun Password(){
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth().verticalScroll(scrollState) modifier = Modifier.fillMaxSize().verticalScroll(scrollState)
) { ) {
val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) }
Text( Text(

View File

@@ -50,7 +50,7 @@ fun DpmPermissions(navCtrl:NavHostController){
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge} val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
var expandCommandBlock by remember{mutableStateOf("")} var expandCommandBlock by remember{mutableStateOf("")}
Column( Column(
modifier = Modifier.verticalScroll(rememberScrollState()), modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Row( Row(

View File

@@ -34,7 +34,7 @@ fun AppSetting(navCtrl:NavHostController){
val verCode = pkgInfo.versionCode val verCode = pkgInfo.versionCode
val verName = pkgInfo.versionName val verName = pkgInfo.versionName
Column(modifier = sections()) { Column(modifier = sections()) {
Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 3.dp),horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxSize().padding(horizontal = 3.dp),horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
Text(text = "Wear", style = typography.titleLarge, color = titleColor) Text(text = "Wear", style = typography.titleLarge, color = titleColor)
Switch( Switch(
checked = isWear, checked = isWear,

View File

@@ -36,7 +36,7 @@ import androidx.core.os.UserManagerCompat
var affiliationID = mutableSetOf<String>() var affiliationID = mutableSetOf<String>()
@Composable @Composable
fun UserManage() { fun UserManage() {
Column(modifier = Modifier.verticalScroll(rememberScrollState())) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
val myContext = LocalContext.current val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java) val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)

View File

@@ -53,7 +53,7 @@ fun UserRestriction(){
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false) val isWear = sharedPref.getBoolean("isWear",false)
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge} val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
Column(modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally){ Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally){
Text(text = "打开开关后会禁用对应的功能",style = bodyTextStyle) Text(text = "打开开关后会禁用对应的功能",style = bodyTextStyle)
if(VERSION.SDK_INT<24){ if(VERSION.SDK_INT<24){
Text(text = "所有的用户限制都需要API24你的设备低于API24无法使用。", style = bodyTextStyle, color = colorScheme.error) Text(text = "所有的用户限制都需要API24你的设备低于API24无法使用。", style = bodyTextStyle, color = colorScheme.error)

View File

@@ -0,0 +1,58 @@
package com.binbin.androidowner.ui.theme
import android.content.Context
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.navigation.NavBackStackEntry
class Animations(myContext: Context){
private val springFade = tween<Float>(durationMillis = 150)
private val springSlide:SpringSpec<IntOffset> = SpringSpec(Spring.DampingRatioNoBouncy, Spring.StiffnessMediumLow, null)
private val navIconSpringSlide:SpringSpec<IntSize> = SpringSpec(Spring.DampingRatioNoBouncy, Spring.StiffnessMediumLow, null)
val navIconEnterTransition:EnterTransition = expandHorizontally(navIconSpringSlide) + fadeIn()
val navIconExitTransition:ExitTransition = shrinkHorizontally(navIconSpringSlide) + fadeOut()
private val screenWidth = myContext.resources.displayMetrics.widthPixels
private val initialOffsetValue = screenWidth/12
private val targetOffsetValue = screenWidth/12
val navHostEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
fadeIn(animationSpec = springFade) +
slideIntoContainer(
animationSpec = springSlide,
towards = AnimatedContentTransitionScope.SlideDirection.End,
initialOffset = {initialOffsetValue}
)
}
val navHostExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
fadeOut(animationSpec = springFade) +
slideOutOfContainer(
animationSpec = springSlide,
towards = AnimatedContentTransitionScope.SlideDirection.Start,
targetOffset = {-targetOffsetValue}
)
}
val navHostPopEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
fadeIn(animationSpec = springFade) +
slideIntoContainer(
animationSpec = springSlide,
towards = AnimatedContentTransitionScope.SlideDirection.End,
initialOffset = {-initialOffsetValue}
)
}
val navHostPopExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
fadeOut(animationSpec = springFade) +
slideOutOfContainer(
animationSpec = springSlide,
towards = AnimatedContentTransitionScope.SlideDirection.Start,
targetOffset = {targetOffsetValue}
)
}
}