不知何故,构建崩溃了,并出现了与导航组件相关的奇怪错误,尽管它以前可以工作,但错误出在生成的类中,就我而言 NativeLanguageSelectionFragmentDirections
这是错误
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (10, 16): Class 'GoToSelectLearningLangAction' is not abstract and does not implement abstract member public abstract val actionId: Int defined in androidx.navigation.NavDirections
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (13, 12): 'getActionId' overrides nothing
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (15, 12): 'getArguments' overrides nothing
Run Code Online (Sandbox Code Playgroud)
这是导航图的代码
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (10, 16): Class 'GoToSelectLearningLangAction' is not abstract and does not implement abstract member public abstract val actionId: Int defined in androidx.navigation.NavDirections
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (13, 12): 'getActionId' overrides nothing
e: C:\Users\David\StudioProjects\android\app\build\generated\source\navigation-args\debug\com\linguistic\linguistic\framework\presentation\loginscreens\ui\main\NativeLanguageSelectionFragmentDirections.kt: (15, 12): 'getArguments' overrides nothing
Run Code Online (Sandbox Code Playgroud)
我在用
"androidx.navigation:navigation-fragment-ktx:2.3.5" …Run Code Online (Sandbox Code Playgroud) 我使用以下代码片段从一个可组合项导航到另一个可组合项,但它有一个默认的淡入淡出动画。我怎样才能删除它?我尝试使用空anim资源,但它不起作用。
navHostController.navigate(
"destination_route",
navOptions {
popUpTo("this_route") {
inclusive = true
}
anim {
enter = R.anim.empty_animation
exit = R.anim.empty_animation
popEnter = R.anim.empty_animation
popExit = R.anim.empty_animation
}
}
)
Run Code Online (Sandbox Code Playgroud)
R.anim.empty_animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--Empty to disable animation-->
</set>
Run Code Online (Sandbox Code Playgroud) 我目前正在我的应用程序中实现导航组件,但似乎发现 NavHostFragment 无论我做什么都不起作用。
我已经尝试过重建、失效和重新启动、更改名称以及更新我的 Android Studio,但似乎没有任何效果。我认为这也是我尝试在 MainActivity.kt 文件中获取 NavController 时出错的原因,因为它返回 null。
安卓工作室 4.0.1 版
nav_graph.xml 图像:
导航图.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="com.example.movieapp.ui.main.MainFragment"
android:label="MainFragment">
<action
android:id="@+id/action_mainFragment_to_searchMovieFragment"
app:destination="@id/searchMovieFragment" />
</fragment>
<fragment
android:id="@+id/searchMovieFragment"
android:name="com.example.movieapp.ui.search.SearchMovieFragment"
android:label="SearchMovieFragment" />
</navigation>
Run Code Online (Sandbox Code Playgroud)
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<include
layout="@layout/appbar" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
主活动.kt
class MainActivity : AppCompatActivity() {
private lateinit var toolbar: …Run Code Online (Sandbox Code Playgroud) 我想BluetoothDevice使用组合导航将 Parcelable 对象 ( ) 传递给可组合对象。
传递原始类型很容易:
composable(
"profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType })
) {...}
Run Code Online (Sandbox Code Playgroud)
navController.navigate("profile/user1234")
Run Code Online (Sandbox Code Playgroud)
但是我不能在路由中传递一个parcelable 对象,除非我可以将它序列化为一个字符串。
composable(
"deviceDetails/{device}",
arguments = listOf(navArgument("device") { type = NavType.ParcelableType(BluetoothDevice::class.java) })
) {...}
Run Code Online (Sandbox Code Playgroud)
val device: BluetoothDevice = ...
navController.navigate("deviceDetails/$device")
Run Code Online (Sandbox Code Playgroud)
上面的代码显然不起作用,因为它只是隐式调用toString().
有没有办法要么序列化Parcelable的String,所以我可以通过它的路线或通过导航参数作为比其他函数的对象navigate(route: String)?
android kotlin android-jetpack-navigation android-jetpack-compose
当我双击同一项目或如果我很快进入每个可组合屏幕时,我会收到一条错误消息,我该如何解决此问题?我尝试改变一些东西,但我无法解决它,而且我找不到任何资源来解决这个问题。
底部导航实施
@Composable
fun BottomNav(
navController: NavController,
bottomNavState: MutableState<Boolean>,
) {
val navItems = listOf(
Screen.HomeScreen,
Screen.BookmarkScreen,
Screen.MyRecipesScreen,
Screen.FavouriteScreen
)
AnimatedVisibility(
visible = bottomNavState.value,
enter = slideInVertically(initialOffsetY = { it }),
exit = slideOutVertically(targetOffsetY = { it }),
content = {
BottomNavigation(
backgroundColor = Color.White,
elevation = 12.dp
) {
val bottomNavBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = bottomNavBackStackEntry?.destination
navItems.forEach { item ->
BottomNavigationItem(
icon = {
Icon(painter = painterResource(id = item.icon), contentDescription = "")
},
label = {
Text(text = …Run Code Online (Sandbox Code Playgroud) kotlin android-jetpack android-jetpack-navigation android-jetpack-compose
我正在开发 Jetpack Compose Navigation 演示,并且有一个嵌套导航图,其中包含两个不同的嵌套路线以及每个嵌套路线的屏幕:
登录图具有三种路线,用于显示三个不同的屏幕
主图有两个用于这些屏幕的路线
嵌套图创建在MainActivity.kt中调用
setContent {
NavigationDemoTheme {
val navController = rememberNavController()
SetupNavGraph(navController = navController)
}
}
Run Code Online (Sandbox Code Playgroud)
文件NestedNavGraph.kt中的函数如下所示:
fun SetupNavGraph(navController: NavHostController) {
NavHost(navController = navController, startDestination = "login_route")
{
loginGraph(navController = navController)
mainGraph(navController = navController)
}
}
Run Code Online (Sandbox Code Playgroud)
在文件LoginNavGraph.kt中,我定义了路线和起始目的地
fun NavGraphBuilder.loginGraph(navController: NavController) {
navigation(startDestination = "login", route = "login_route") {
composable(route = "login") {
LoginScreen(navController = navController)
}
composable(route = "register") {
RegisterScreen(navController = navController) …Run Code Online (Sandbox Code Playgroud) navigation android kotlin android-jetpack-navigation android-jetpack-compose
由于从 Android 33 开始旧版本Activity.onBackPressed()已被弃用,那么以编程方式调用它的更好方法是什么?
例子:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
// Handle default back arrow click
android.R.id.home -> {
onBackPressed()
}
...
Run Code Online (Sandbox Code Playgroud)
我们可以创建并添加这样的OnBackPressedCallback内容onBackPressedDispatcher。
onBackPressedDispatcher.addCallback(
this, // Lifecycle owner
backPressedCallback
)
private val backPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (viewPager.currentItem != 0)
viewPager.setCurrentItem(0, true)
else
finish()
}
}
Run Code Online (Sandbox Code Playgroud)
然后将旧的替换onBackPressed为
// Handle default back arrow click
android.R.id.home -> {
backPressedCallback.handleOnBackPressed()
}
Run Code Online (Sandbox Code Playgroud)
但我看到了这个公共方法onBackPressedDispatcher,想知道是否可以用它来代替。
onBackPressedDispatcher.onBackPressed() …Run Code Online (Sandbox Code Playgroud) android onbackpressed android-jetpack android-jetpack-navigation android-tiramisu
我有一个登录屏幕,当登录成功并且视图模型更新可变状态变量时,我的期望是调用一个新的可组合函数来显示新屏幕,并删除登录屏幕。问题是,当Screen.AccountsScreen显示新屏幕(又名)时,其内容不断闪烁/重绘,并且登录表单也会发生同样的情况,而该登录表单永远不会被破坏(我知道这一点是因为日志消息“Recomponing...”被无休止地打印) 。我认为发生这种情况是因为isLoginSuccessful状态始终为真。看来我需要一个只能消耗一次的事件,这是正确的吗?如果是这样,我该怎么做?
LoginViewModel.kt
@HiltViewModel
class LoginViewModel @Inject constructor() : ViewModel() {
var isLoginSuccessful by mutableStateOf(false)
var errorMessage by mutableStateOf("")
fun onLoginClick(email: String, password:String) {
errorMessage = ""
if (credentialsValid(email, password)) {
isLoginSuccessful = true
} else {
errorMessage = "Email or password invalid"
isLoginSuccessful = false
}
}
}
Run Code Online (Sandbox Code Playgroud)
LoginScreen.kt
@Composable
fun loginScreen(
navController: NavController,
viewModel: LoginViewModel = hiltViewModel()
) {
println("Recomponing...")
// Here gos the code for the login form
if (viewModel.isLoginSuccessful) {
navController.navigate(Screen.AccountsScreen.route) { …Run Code Online (Sandbox Code Playgroud) android kotlin android-jetpack-navigation android-jetpack-compose
在 Navhost 导航期间,我发现可组合屏幕多次重新组合。因此,我的 ViewModel 也多次调用 API 数据源。
@Composable
fun MainView() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
topBar = { TopBar(
toolbarTitle = stringResource(id = R.string.app_name),
scope = scope,
scaffoldState = scaffoldState
) },
drawerContent = {
DrawerView(scope = scope, scaffoldState = scaffoldState, navController = navController)
},
) {
NavGraph(navController = navController)
}
}
@Composable
fun NavGraph(navController: NavHostController) {
NavHost(navController, startDestination = NavDrawerItem.Repositories.route) {
composable(NavDrawerItem.Repositories.route) {
RepoListView(getViewModel())
}
composable(NavDrawerItem.EmojiList.route) { …Run Code Online (Sandbox Code Playgroud) android android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation compose-recomposition
我正在尝试在 2 个片段 BlankFragment 和 BlankFragment2 之间使用共享元素动画。BlankFragment 有一个回收器视图,而 BlankFragment2 是一个详细信息屏幕。他们共享一张图片,而我正在使用新的导航组件。
在 BlankFragment 中,我正在使用共享图像的转换名称构建FragmentNavigator.Extras附加内容并将其传递给我的调用navigate(因为它是一个回收器视图,并且这些需要是唯一的),
在 BlankFragment2 中,我收到此名称,将其设置为我的图像并设置 setSharedElementEnterTransition
结果是进入动画工作正常但退出/返回没有,我试过设置它们而不是设置它们(因为我相信导航组件应该为我处理这个)有人可以帮忙吗?
MainActivity 导航设置
private void setNavigation() {
navController = Navigation.findNavController(this, R.id.main_fragment);
NavigationUI.setupActionBarWithNavController(this, navController);
}
Run Code Online (Sandbox Code Playgroud)
处理后退按钮
@Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.main_fragment).navigateUp()
|| super.onSupportNavigateUp();
}
Run Code Online (Sandbox Code Playgroud)
空白片段点击
@Override
public void onClick(View view, int position) {
NavController navController = Navigation.findNavController(recyclerView);
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder().addSharedElement(view, view.getTransitionName()).build();
BlankFragmentDirections.ActionBlankFragmentToBlankFragment2 directions = BlankFragmentDirections.actionBlankFragmentToBlankFragment2(view.getTransitionName());
navController.navigate(directions,extras);
}
Run Code Online (Sandbox Code Playgroud)
BlankFragment2 onCreate 带有返回/退出转换
@Override
public void onCreate(Bundle savedInstanceState) …Run Code Online (Sandbox Code Playgroud) android android-transitions material-design shared-element-transition android-jetpack-navigation