android 控件 堆叠

When navigating in a mobile app, the screens opened after one another form a stack, the back stack. Just like pages in a book, moving forward and backward in a back stack feels natural and doesn’t require conscious thinking. There are some minor differences in the way the two dominating platforms and even particular apps build and handle their back stacks, but we are used to have a back stack of some kind and this is why it is so disturbing when we don’t get one.

在移动应用程序中导航时,屏幕依次打开,形成一个堆栈,即后堆栈。 就像书中的页面一样,在后退堆栈中前后移动感觉很自然,不需要有意识的思考。 这两个主导平台甚至特定应用程序构建和处理其后向堆栈的方式存在一些细微的差异,但是我们习惯于使用某种类型的后向堆栈,这就是为什么当我们没有得到一个后向堆栈时如此令人不安的原因。

This can happen when the app is started by another app or is launched from a deep link or notification, or any other way when the app is not started at the "Start destination" — the first screen that is presented when starting the app fresh.

当该应用程序由另一个应用程序启动或从深层链接或通知启动时,或者在未在“启动目标”(未重新启动应用程序时显示的第一个屏幕)中启动该应用程序时,可能会发生这种情况。

In the case of launching the app from the launcher, building the back stack doesn’t require any work, the stack is building itself. But starting the app from a link or from a notification presents a whole new situation. In these cases the app is rarely needed to start from the "Start destination", but from different destinations that are deep in the stack usually. Such application open events replace whatever current back stack the app has at that moment, with a synthetic back stack as detailed in the Principles of navigation.

从启动器启动应用程序的情况下,构建后置堆栈不需要任何工作,而是由堆栈自行构建。 但是从链接或通知启动应用程序会带来全新的情况。 在这些情况下,很少需要从“开始目标”启动应用程序,而是通常从堆栈深处的不同目标启动。 此类应用程序打开事件将使用导航原理中详细介绍的合成后备堆栈来替换应用程序当时具有的当前后备堆栈。

The Android Navigation Component supports deep linking and building synthetic back stacks, but to achieve the often desired result that is that

Android导航组件支持深层链接和构建合成后向堆栈,但要达到通常所需的结果,那就是

"it should match a back stack that could have been achieved by organically navigating through the app."

“它应该与通过在应用程序中进行自然导航可以实现的后向堆栈相匹配。”

may need some setup.

可能需要一些设置。

Let's try it out with a simple application consisting of three fragments (Root, Level1 and Level2) that can be opened sequentially. The navigation graph looks like this:

让我们用一个简单的应用程序进行尝试,该应用程序包含三个可以依次打开的片段(Root,Level1和Level2)。 导航图如下所示:

The app is deep link aware with a few lines of code in two files. AndroidManifest:

该应用程序具有深层链接意识,在两个文件中包含几行代码。 AndroidManifest:

...<activity android:name=".MainActivity"><nav-graph android:value="@navigation/main_navigation" /><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter android:autoVerify="true"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><dataandroid:host="properbackstack.com"android:pathPrefix="/level1"android:scheme="https" /><dataandroid:host="properbackstack.com"android:pathPrefix="/level1/level2"android:scheme="https" /></intent-filter></activity>...

And the navigation graph:

和导航图:

...<fragmentandroid:id="@+id/level1Fragment"android:name="com.vokod.properbackstack.Level1Fragment"android:label="Level 1"tools:layout="@layout/fragment_level1"><actionandroid:id="@+id/action_level1Fragment_to_level2Fragment"app:destination="@id/level2Fragment" /><deepLink app:uri="https://properbackstack.com/level1" /></fragment><fragmentandroid:id="@+id/level2Fragment"android:name="com.vokod.properbackstack.Level2Fragment"android:label="Level 2"tools:layout="@layout/fragment_level2"><deepLink app:uri="https://properbackstack.com/level1/level2" /></fragment>...

If we try it out with the link

如果我们通过链接尝试一下

https://properbackstack.com/level1

https://properbackstack.com/level1

it all works fine. The app is opened with Level1 fragment on top, and navigating back one time gets the user to the Root fragment.

一切正常。 打开该应用程序,并在其顶部显示Level1片段,向后浏览一次可将用户引导至Root片段。

But if we try it with

但是如果我们尝试

https://properbackstack.com/level1/level2

https://properbackstack.com/level1/level2

it is not as expected. The app is opened with Level2 fragment on top all right, but navigating back one time gets the user — again — to fragment Root. Fragment Levell is omitted. Why?

这不是预期的。 该应用程序打开时,首先显示了Level2片段,但向后浏览一次,会再次使用户对Root进行片段化。 片段Level1被省略。 为什么?

If we open up the NavDeepLinkBuilder class reference, it is seen that:

如果我们打开NavDeepLinkBuilder类参考 ,则会看到:

When this deep link is triggered:

触发此深层链接时:

The task is cleared.

任务已清除。

The destination and all of its parents will be on the back stack.

目的地及其所有父项将位于后堆栈。

Calling NavController.navigateUp() will navigate to the parent of the destination.

调用NavController.navigateUp()将导航到目标的父级。

Then why is Level2 fragment not on the back stack? The answer is in the second sentence:

那么为什么Level2片段不在堆栈上? 答案在第二句话中:

The parent of the destination is the start destination of the containing navigation graph.

目标的父级是包含的navigation graphstart destination

By the default behavior, only the start destination of the navigation graph is considered a parent, and fragment Level2 is not the start destination. But then how to build the natural back stack of the app? The deep linking guide might have a suggestion:

默认行为是,仅导航图的起始目标被视为父目标,而片段Level2不是起始目标。 但是,如何构建应用程序的自然后备堆栈呢? 深层链接指南可能有建议:

When a user opens your app via an explicit deep link, the task back stack is cleared and replaced with the deep link destination. When nesting graphs, the start destination from each level of nesting — that is, the start destination from each <navigation> element in the hierarchy—is also added to the stack.

当用户通过显式深层链接打开您的应用程序时,将清除任务后退堆栈,并将其替换为深层链接目标。 嵌套图形时 ,还将每个嵌套级别的起始目标(即,层次结构中每个<navigation>元素的起始目标)添加到堆栈中。

This means that nesting navigation graphs can be the solution. If the navigation graph of the sample application is refactored so that there is a root navigation graph with the root fragment as start destination and a nested graph as the second destination, and in the nested graph, the start destination is the Level1 fragment and the second destination is the Level2 fragment, the deep link back stack will be the same as the original back stack.

这意味着嵌套导航图可以作为解决方案。 如果重构了示例应用程序的导航图,以便有一个根导航图,其中根片段为起始目的地,而嵌套图为第二个目的地,并且在嵌套图中,起始目的地为Level1片段,第二个为destination是Level2片段,深层链接回栈将与原始回栈相同。

<?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/main_navigation"app:startDestination="@id/rootFragment"><fragmentandroid:id="@+id/rootFragment"android:name="com.vokod.properbackstack.RootFragment"android:label="Root"tools:layout="@layout/fragment_root"><actionandroid:id="@+id/action_rootFragment_to_level1Fragment"app:destination="@id/level1navigation" /></fragment><navigation android:id="@+id/level1navigation"app:startDestination="@id/level1Fragment"><fragmentandroid:id="@+id/level1Fragment"android:name="com.vokod.properbackstack.Level1Fragment"android:label="Level 1"tools:layout="@layout/fragment_level1"><actionandroid:id="@+id/action_level1Fragment_to_level2Fragment"app:destination="@id/level2Fragment" /><deepLink app:uri="https://properbackstack.com/level1" /></fragment><fragmentandroid:id="@+id/level2Fragment"android:name="com.vokod.properbackstack.Level2Fragment"android:label="Level 2"tools:layout="@layout/fragment_level2"><deepLink app:uri="https://properbackstack.com/level1/level2" /></fragment></navigation>
</navigation>

So far it is easy and straightforward, but deep links rarely are static links like the ones above, and the case is a bit more complicated if they contain path and query parameters. I won't explain deep link parameters here, the documentation does a good job on that, we only need to know that to build proper synthetic back stacks, parameters should be translated to fragment arguments.

到目前为止,这很容易和直接,但是深层链接很少是像上面那样的静态链接, 如果它们包含path和query参数 ,情况会更复杂一些 。 我不会在这里解释深层链接参数,文档在这方面做得很好,我们只需要知道要构建适当的综合后备堆栈,就应该将参数转换为片段参数。

But there is a catch: the parameters have to contain all the arguments of every fragment on the back stack (or, to turn it around, the parameters must suffice as arguments for every fragment) in order for the fragments on the back stack to be able to load their content when the user navigates back.

但是有一个陷阱:参数必须包含后堆栈上每个片段的所有参数(或者,要解决这个问题,参数必须足以作为每个片段的参数),以使后堆栈上的片段成为可以在用户向后导航时加载其内容。

If the app shall open the link

如果应用程序应打开链接

https://properbackstack.com/level1/{number}

https://properbackstack.com/level1/{number}

in fragment Level1 and

在片段Level1和

https://properbackstack.com/level2/{word}

https://properbackstack.com/level2/{word}

in fragment Level2, proper back stack cannot be achieved because when opening the second link and navigating back from fragment Level2 to fragment Level1, an IllegalArgumentException is thrown by fragment Level1, missing the argument: number. Fragment Level2 does not need number argument by itself, but have to handle it for building proper back stack. The level 2 link will have to contain both arguments, and look something like this:

在片段Level2中,由于打开第二个链接并从片段Level2导航回片段Level1时,片段Level1抛出了IllegalArgumentException,缺少参数:number,因此无法实现正确的后向堆栈。 片段Level2本身不需要数字参数,但必须处理它以构建适当的后向堆栈。 2级链接将必须包含两个参数,并且看起来像这样:

https://properbackstack.com/level2/{number}/{word}

https://properbackstack.com/level2/{number}/{word}

One more thing: remember, the navigation graph is nested and the nested graph's start destination is fragment Level1. And as fragment Level1 needs an argument to start, so does the nested navigation graph. The final navigation graph will look like this:

还有一件事:请记住,导航图是嵌套的,而嵌套图的起始目标是片段Level1。 由于片段Level1需要一个参数来启动,因此嵌套的导航图也是如此。 最终的导航图将如下所示:

<?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/main_navigation"app:startDestination="@id/rootFragment"><fragmentandroid:id="@+id/rootFragment"android:name="com.vokod.properbackstack.RootFragment"android:label="Root"tools:layout="@layout/fragment_root"><actionandroid:id="@+id/action_rootFragment_to_level1Fragment"app:destination="@id/level1navigation" /></fragment><navigationandroid:id="@+id/level1navigation"app:startDestination="@id/level1Fragment"><argumentandroid:name="number"app:argType="integer" /><fragmentandroid:id="@+id/level1Fragment"android:name="com.vokod.properbackstack.Level1Fragment"android:label="Level 1"tools:layout="@layout/fragment_level1"><actionandroid:id="@+id/action_level1Fragment_to_level2Fragment"app:destination="@id/level2Fragment" /><argumentandroid:name="number"app:argType="integer" /><deepLink app:uri="https://properbackstack.com/level1/{number}" /></fragment><fragmentandroid:id="@+id/level2Fragment"android:name="com.vokod.properbackstack.Level2Fragment"android:label="Level 2"tools:layout="@layout/fragment_level2"><argumentandroid:name="word"app:argType="string" /><argumentandroid:name="number"app:argType="integer" /><deepLink app:uri="https://properbackstack.com/level2/{number}/{word}" /></fragment></navigation>
</navigation>

This solution works similarly with notifications as well, where the NavDeepLinkBuilder class can be utilized to inject the arguments and select the navigation graph and destination.

此解决方案也适用于通知,在该通知中,可以使用NavDeepLinkBuilder类来注入参数并选择导航图和目标。

NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID).setSmallIcon(R.drawable.ic_launcher_foreground).......setContentIntent(NavDeepLinkBuilder(context).setComponentName(MainActivity::class.java).setGraph(R.navigation.main_navigation).setDestination(R.id.level2Fragment).setArguments(Bundle().apply {putInt("number", 9876)putString("word", "Welcome from notification")}).createPendingIntent())).build()

The solution above might not be a universal silver bullet for all the synthetic back stack related issues and might not even solve your app's particular navigation needs, but I hope you found it useful. Let me know if you did :)

上面的解决方案可能不是解决所有与合成后置堆栈相关的问题的万能灵丹妙药,甚至可能无法解决您应用程序的特定导航需求,但我希望您发现它有用。 让我知道你是否做过:)

The sample application can be found here:

可以在这里找到示例应用程序:

https://github.com/vokod/ProperBackStack/tree/notification

https://github.com/vokod/ProperBackStack/tree/notification

The three branches explain the three topic discussed:

三个分支解释了讨论的三个主题:

— static deep link back stack,

— 静态深层链接回栈 ,

— dynamic deep link back stack,

— 动态深层链接回栈 ,

— notification back stack.

— 通知返回堆栈 。

翻译自: https://medium.com/swlh/proper-back-stack-on-android-every-time-4a811f8ab78c

android 控件 堆叠


http://www.taodudu.cc/news/show-4980947.html

相关文章:

  • Jetpack-Navigation使用第一部分
  • eclipse java3d_Using Xj3D in your Java Application
  • 《Android 基础(四十九)》Navigation Of JetPack【译】
  • tf.reset_default_graph()
  • tensorflow与深度学习之一
  • 从设计稿到demo
  • Xposed插件的使用(一)进行简单的Hook
  • android xposed如何写,Xposed插件开发入门详解
  • 【Android视频号③ Xposed插件编写】
  • xposed插件加固保护方案以及对华为方舟编译器的思考
  • Xposed插件开发手册(2):Xposed插件开发入门
  • Python 打印菱形
  • 【C语言经典例题】打印菱形
  • 详细讲解:打印菱形(随心所欲版)
  • matlab一元二次方程的求解
  • C语言——一元二次方程求解
  • 一元二次方程组的输入
  • 一元二次方程组c语言代码,一元二次方程求解程序完整代码
  • 使用Python批量旋转,镜像图片
  • 便捷式备份系统并还原
  • 【Amber】分子动力学结果分析(二)PMF
  • 挂载内存文件系统pmfs
  • python打开文件的语法_python27语法Python文件打开方式实例详解【a、a+、r+、w+区别】...
  • fix SMD计算自由能(PMF)之umbrella抽样
  • 生于MVP,死于PMF
  • 一个依赖搞定Spring Boot 配置文件脱敏
  • nutz on gae 数据存储区 1.1 pmf
  • android wifi 配置文件,androidWiFiConfiguration 资源类型
  • 大气颗粒物 PMF 源解析实践技术应用
  • c语言读取 mat文件的函数,vc对.mat文件的读取

android 控件 堆叠_每次在Android上正确地向后堆叠相关推荐

  1. android 控件发光_如何在android中的按钮周围制作动画/常量发光效果?

    的按钮有一个背景绘制的图像,我只是想拥有它周围的发光效果,使它有点与音乐播放 我已经搜查各地的多个线程共鸣,他们要么只是一个ImageView的,或在压制,或位图,所以不一定是我寻求 这里是我的按钮X ...

  2. 最简单也最难——如何获取到Android控件的高度,获取android控件

    最简单也最难--如何获取到Android控件的高度,获取android控件 问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth ...

  3. android上传文件用哪个布局,每周总结20130821——android控件的尺寸、http文件上传...

    Android控件的尺寸 android开发中,可以通过编写XML格式的布局文件来实现布局,也可以用纯代码进行布局,通常都是选择XML文件布局.在XML布局文件中,与控件的尺寸有关的属性有androi ...

  4. android控件属性文档,1.Android控件属性收集

    最近在做ui方面的工作,收集这些属性方便日后快速查找 @autho: zlw email: 739043667@qq.com 欢迎交流 目录: 一.TextView.EditText 属性 二.Car ...

  5. android 控件方向旋转90度,android – 旋转视图层次90度

    我正在工作的一个子类的FrameLayout,应该是将所有的孩子旋转90度.我这样做是为了克服Android 2.1及以下版本中仅存在于风景中的摄像机限制,将活动放置在横向,但将我的摄像机覆盖放置在此 ...

  6. android 控件监听方法是,Android | Android中监听Button的实现

    Android中监听Button的实现 单按钮监听 2018-04-27_061911.jpg 1.在按钮所属的父Activity里,创建按钮变量 private Button mBtnTextVie ...

  7. Android控件系列之RadioButtonRadioGroup

    2019独角兽企业重金招聘Python工程师标准>>> 学习目的: 1.掌握在Android中如何建立RadioGroup和RadioButton 2.掌握RadioGroup的常用 ...

  8. Android控件默认点击效果

    Android控件默认点击效果 Android最简单的默认点击效果: android:background="?android:attr/selectableItemBackground&q ...

  9. android控件的touch事件_聊聊Android嵌套滑动

    聊聊Android嵌套滑动 最近工作中遇到了需求是使用 Bottom-Sheet 交互的弹窗,使用了 design 包里面的 CoordinatorLayout 和 BottomSheetBehavi ...

最新文章

  1. Oracle数据库导入导出命令!
  2. Linux下查找nginx配置文件路径
  3. 几种典型的内存溢出案例,都在这儿了!
  4. PHP新增与修改的区分
  5. 怎么导出链接_如何导出CocosCreator项目供cocos2dx加载
  6. (转)iOS编程高性能之路-自动化编译脚本(1)
  7. 挖地雷(信息学奥赛一本通-T1262)
  8. STM32F405 HAL库 STM32CUBE开发
  9. 汇编:1位16进制数到ASCII码转换
  10. Mac上Chrome浏览器快捷键汇总
  11. HDMI转PGA电脑没有声音处理方法
  12. CTF-隐写术(三)
  13. 谈谈区块链正经的商用场景!
  14. 韩国区块链步入快车道:SM、Kakao、三星、LG等巨头ALL IN
  15. Spring Security 配置白名单访问后,仍然报错403
  16. 三大运营商物联卡哪家网络稳定
  17. 电动车电池管理系统c语言实训,电动车控制器C语言源代码复习课程.doc
  18. 4 万字超强总结!Java 这些必备基础知识不可少
  19. 动手做个VR眼镜,找回童年的感觉
  20. hawei 9306 snmp 详细oid

热门文章

  1. div结合css布局bbs首页
  2. Python/python出租车计费
  3. Linux运维之top命令解析
  4. STM32IO模拟串口接收发送(stm32f030)
  5. PHP开发API接口注意事项
  6. DVWA 查看默认密码
  7. python r语言培训_R语言和Python区别有哪些?老男孩Python脱产班
  8. javaweb项目相对路径与绝对路径
  9. 对口升学计算机试卷分析,语文试卷分析
  10. vue使用font-icon