我想使用 saveStateHandle 将一些数据从活动直接传递到片段的视图模型。
在我的活动中我有:
navController.addOnDestinationChangedListener { controller, _, _ ->
controller.currentBackStackEntry?.savedStateHandle?.set(
"foo",
"bar"
)
}
Run Code Online (Sandbox Code Playgroud)
所以viewModel中的代码如下所示:
MyViewModel(state: SavedStateHandle) : ViewModel() {
init {
state
?.getStateFlow("foo", "")
?.onEach { /* do something */ }
?.launchIn(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,期望值bar永远不会被发出。
我已经检查了Fragment本身,数据就在那里:
val handle = findNavController().currentBackStackEntry?.savedStateHandle
handle?.getLiveData<String>("foo")?.observe(viewLifecycleOwner) {
// here it is
}
Run Code Online (Sandbox Code Playgroud)
但是是否有可能将数据直接传递到 viewModel 的 savingStateHandle ?我相信应该是这样,因为导航器以某种方式通过了。
android android-savedstate android-viewmodel android-jetpack-navigation viewmodel-savedstate
我正在尝试添加一个侦听器,并在 Jetpack Compose 中完成导航转换时接收回调。
我尝试使用 NavController API addOnDestinationChangedListener,但它会立即发送到我的侦听器,并且不会等待合成完成。
val navController = rememberNavController()
// Register the destination changed listener
navController.addOnDestinationChangedListener { _, destination, _ ->
// destination change is sent immediately and isnt waiting for the composable to finish
}
Run Code Online (Sandbox Code Playgroud)
我的目标是添加一个侦听器,仅在合成完成且目的地更改后才会触发该侦听器。
像这样的东西:
// Register the transition finished listener
navController.transitionFinished{ _, destination ->
// Do something when the navigation transition has finished
}
NavHost(navController = navController, startDestination = "Home") {
composable("Home") {
// THE CALLBACK IS FIRED HERE, IMMEDITIETLY
Text("FIRST SITE") …Run Code Online (Sandbox Code Playgroud) android kotlin android-jetpack android-jetpack-navigation android-jetpack-compose
我打电话setOnApplyWindowInsetsListener给我的视图添加填充/边距。我的 XML 包含android:fitsSystemWindows="true"
setOnApplyWindowInsetsListener被调用两次后(第二次插入 0)。
为什么 Android 返回 insets 两次并且第二次 insets 值为零?为什么当我将其设置为第一个值时,我的填充不适用?
代码:
drawer.setOnApplyWindowInsetsListener((v, insets) -> {
profileButton.setPadding(
profileButton.getPaddingLeft(),
profileButton.getPaddingTop(),
insets.getSystemWindowInsetBottom(),
profileButton.getPaddingBottom()
);
Timber.d("Inset applied: %d", insets.getSystemWindowInsetBottom());
return insets;
});
Run Code Online (Sandbox Code Playgroud)
控制台输出:
D/MainActivity: Inset applied: 53
D/MainActivity: Inset applied: 0
Run Code Online (Sandbox Code Playgroud) android android-layout android-jetpack android-jetpack-navigation
我正在使用带有 BottomNavigationView 的高级导航组件。
在一个选项卡中,我有 ViewPager2。当我第一次点击 Tab 时工作正常。
尽管第二次出现该选项卡应用程序不断崩溃。如果有人可以帮助,下面是崩溃日志,谢谢。
java.lang.IllegalArgumentException at androidx.core.util.Preconditions.checkArgument(Preconditions.java:36) at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:140) at androidx.recyclerview.widget.set.RecyclerView() RecyclerView.java:1206) at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1158) at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:460) at com。.ui.home.history.HistoryFragment.setupAdapter(HistoryFragment.kt:25) 在 com。.ui.home.history.HistoryFragment.viewSetup(HistoryFragment.kt:21) at com.****.base.BaseFragment.onViewCreated(BaseFragment.kt:37) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager. java:332) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356) 在 androidx.fragment.app.FragmentManager.moveFragmentToFragmentManager.moveFragment(FragmentManager.java:1187) .java:1434) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497) 在 androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625) 在 androidx.fragment.app.FragmentManager.dispatchCreatedActivity FragmentManager.java:2577) 在 androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722) 在 androidx.fragment.app.FragmentStateManager。activityCreated(FragmentStateManager.java:346) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188) at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224) at androidx.fragment.app.Fragment .executeOpsTogether(FragmentManager.java:1997) 在 androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953) 在 androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849) FragmentManager$4.run(FragmentManager.java:413) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop( Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6940) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os。RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
这是我的片段代码:
private val …Run Code Online (Sandbox Code Playgroud) android android-recyclerview android-jetpack android-viewpager2 android-jetpack-navigation
我开始使用 Jetpack Compose,我对它非常满意。我替换了几个由@Composable函数在 xml 中定义的布局。
当我回到我的 Navigation-xml 时,我注意到每个屏幕内的预览都是通过tools:layout属性完成的。以及对 xml 中布局的属性引用。不是一个@Composable函数。
@Composable是否已经有一种方法可以从导航 xml 中引用函数,tools:layout以便整个流程的预览可见?
我正在尝试新的喷气背包库“ compose-navigation ”。
根据docs,要导航到路线,我应该使用navigate()采用String 的方法。
navController = rememberNavController()
// navigate
navController.navigate("/another_route")
Run Code Online (Sandbox Code Playgroud)
但是,不存在这样的方法, navigate(String)并且出现编译错误。
我错过了什么?
假设我的应用程序如下所示
@Composable
fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController, startDestination = Route.Home.route) {
/// other composes
composable("Home") { HomeCompose(navController) }
}
}
@Composable
fun HomeCompose(navController: NavHostController) {
ChildCompose(navController)
}
@Composable
fun ChildCompose(navController: NavHostController) {
navController.navigate("")
}
Run Code Online (Sandbox Code Playgroud)
我想访问嵌套可组合项中的 navController 进行导航,但我不想将 navController 从父可组合项传递到子可组合项,如上所述
无论如何,是否可以从 NavHost 内的任何位置访问 navController,而无需通过可组合层次结构传递它
编辑:现在,我可以使用 CompositionLocalProvider 访问嵌套组合中的 navController,如下所示
val AppNavController = compositionLocalOf<NavHostController>() { error("NavHostController error") }
@Composable
fun AppNavigation() {
val navController = rememberNavController()
CompositionLocalProvider(
AppNavController provides navController
) {
NavHost(navController, startDestination = Route.Home.route) {
/// other composes …Run Code Online (Sandbox Code Playgroud) android android-jetpack android-jetpack-navigation android-jetpack-compose
我使用 jetpack compose 和导航撰写库来从一个屏幕导航到下一个屏幕。通常你会有一个ViewModel负责用户交互的(例如:)viewModel.addItem()。为了完成 addItem 命令,我想通过显示另一个屏幕navController.navigate()。其ViewModel本身通过 注入到可组合项中hiltNavGraphViewModel()。
现在的问题是:我怎样才能将其注入到刀柄NavController中?ViewModel
@HiltViewModel
class ScreenViewModel @Inject constructor(
private val navController: NavController // where does it come from?
) : ViewModel() {
fun addItem() {
navController.navigate("add-item-screen")
}
}
Run Code Online (Sandbox Code Playgroud)
它NavController是通过rememberNavController()可组合层次结构中的 up 方法创建的。我也不想将控制器传递到可组合层次结构或使用 CompositionLocal。首选方法是让控制器在 ViewModel 中可用。
android-jetpack-navigation android-jetpack-compose dagger-hilt
根据这个示例,我在嵌套导航图中实现了共享 viewModel。
嵌套图:
private fun NavGraphBuilder.accountGraph(navController: NavHostController) {
navigation(
startDestination = "main",
route = "account") {
composable("main") {
val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
//... ui ...
}
composable("login") {
val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
//... ui ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
导航主机:
@Composable
private fun NavHost(navController: NavHostController, modifier: Modifier = Modifier){
NavHost(
navController = navController,
startDestination = MainScreen.Home.route,
modifier = modifier
) {
composable("home") { HomeScreen(hiltViewModel()) }
composable("otherRoute") { OtherScreen(hiltViewModel()) }
accountGraph(navController)
}
}
Run Code Online (Sandbox Code Playgroud)
底部导航栏:
@Composable
private fun ButtonNav(navController: NavHostController) …Run Code Online (Sandbox Code Playgroud) android android-jetpack-navigation android-jetpack-compose dagger-hilt
我已尝试从本文中进行伴奏库导航,并且我想防止当我单击底部工作表的背景(灰色区域)时关闭底部工作表并使其根本不可单击,我该如何实现这一点?
这是链接中的代码
@Composable
fun MyApp() {
val navController = rememberNavController()
val bottomSheetNavigator = rememberBottomSheetNavigator()
navController.navigatorProvider += bottomSheetNavigator
ModalBottomSheetLayout(
bottomSheetNavigator = bottomSheetNavigator
) {
NavHost(navController, startDestination = "home") {
composable(route = "home") {
Button(onClick = { navController.navigate("sheet") }) {
Text("Click me to see something cool!")
}
}
bottomSheet(route = "sheet") {
Text("This is a cool bottom sheet!")
Button(onClick = { navController.navigate("home") }) {
Text("Take me back, please!")
}
Spacer(modifier = Modifier.padding(200.dp))
}
}
}
}
Run Code Online (Sandbox Code Playgroud) android-jetpack-navigation android-jetpack-compose jetpack-compose-accompanist
android-jetpack-navigation ×10
android ×8
dagger-hilt ×2
jetpack-compose-accompanist ×1
kotlin ×1