请选择 进入手机版 | 继续访问电脑版

Android Jetpack 架构组件之 Navigation

[复制链接]
钟启航 发表于 2021-1-2 17:49:24 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
一、关键字段的表明

Kotlin语言情况下在Fragment内里操纵控件的注意事项:
  1. 在onCreateView()方法和onStart()方法内里直接通过id操纵控件的话,会要求必须加findViewById()获取控件id,否则就会报"must not be null"这个错误。但是在onViewCreated()方法内里就不消这样。别的自界说的方法内里也是必须获取控件id。可以这么明确:在Fragment内里,除了在onViewCreated()方法内里直接操纵控件大概调用操纵控件的方法外,其他任何地方操纵控件大概调用操纵控件的方法都是需要通过findViewById()获取控件id,否者就会报上面的错误。
复制代码
Navigation各字段寄义:
1、Activity对应的xml内里,fragment标签示例以及几个关键字的寄义:

  1. [/code] [b]android:id[/b]:在Activity内里用于通过supportFragmentManager获取NavHostFragment对象。
  2. [b]android:name[/b]:是NavHostFragment,它实现了NavHost,这是一个用于放置管理destination的空视图。指向NavHost的实现类NavHostFragment。
  3. [b]app:navGraph[/b]:指向Navigation graph设置文件,用于将NavHostFragment和nav_graph.xml关联起来。
  4. [b]app:defaultNavHost[/b]:默认值为false,当该值为false的时候,当前Activity中的Fragment使用了Navigation,且使用Navigation跳转到下一个Fragment,在下一个Fragment页面中点击了Back键会退出当前Activity。为true的时候是回到上一个Fragment中,如果上一个Fragment为null才会退出当前Activity。类似于我们处理处罚WebView的back事件。
  5. [size=4]2、navigation文件夹下nav_host.xml文件示例及内里关键字段的寄义:[/size]
  6. [code]                                                                                                                           
复制代码
name:指定Fragment的路径。
tools:layout:指定结构文件,如果不设置该属性在Design面板会看不见预览。
action:字面明确就是动作,作用是fragment之间举行切换。
app:startDestination:指定这个Fragment是start-destination。
app:destination:目标地,指定要跳转到Fragment的id。
app:id:界说这个action的id,代码里执行跳转时要用到。
enterAnim、exitAnim、popEnterAnim、popExitAnim:是页面切换和弹窗动画
如果某个Fragment是最后一个Fragment,那么我们就可以直接省略他的action。
二、Navigation的使用步调

1、app的build.gradle导入依赖:

  1. def nav_version = "2.3.0"implementation "androidx.navigation:navigation-fragment:$nav_version"implementation "androidx.navigation:navigation-ui:$nav_version"implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"implementation "androidx.navigation:navigation-ui-ktx:$nav_version"implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
复制代码
并在这个build.gradle内里添加:
  1. apply plugin: "androidx.navigation.safeargs"
复制代码
2、在项目工程的build.gradle添加如下依赖:

  1. classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
复制代码
3、新建几个Fragment并关联结构:

ZeroFragment及对应的xml结构文件:
xml文件结构
  1. [/code] kotlin代码实现:
  2. [code]class ZeroFragment :Fragment(){    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        return inflater.inflate(R.layout.fragment_zero, container, false)    }}
复制代码
OneFragment及对应的xml结构文件:
xml文件结构:
  1.         
复制代码
kotlin代码实现:
  1. class OneFragment :Fragment(){    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        return inflater.inflate(R.layout.fragment_one, container, false)    }}
复制代码
HomeFragment及对应的xml结构文件:
xml文件结构:
  1.                     
复制代码
kotlin代码实现:
  1. class HomeFragment :Fragment(){    var mActivity:NavigationPrimaryActivity? = null    override fun onAttach(context: Context) {        super.onAttach(context)        mActivity = (context as NavigationPrimaryActivity)    }        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        return inflater.inflate(R.layout.fragment_home, container, false)    }        //在onCreateView()方法和onStart()方法内里直接通过id操纵控件的话,会要求必须加findViewById()获取控件id,    //否则就会报"must not be null"这个错误。    //但是在onViewCreated()方法内里就不消这样。别的自界说的方法内里也是必须获取控件id。    //可以这么明确:在Fragment内里,除了在onViewCreated()方法内里直接操纵控件大概调用操纵控件的方法外,    //其他任何地方操纵控件大概调用操纵控件的方法都是需要通过findViewById()获取控件id,否者就会报上面的错误。    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {        super.onViewCreated(view, savedInstanceState)        operationView()    }        fun operationView() {        open1.setOnClickListener {                            mActivity?.printLoginfo("不能滑动,没什么鸟用")                }        tvTitle.text = "皇者号天令"    }}
复制代码
4、新建Navigation graph资源文件

1)、在工程的res文件夹下创建新的文件夹:navigation
2)、单击navigation文件夹右键菜单选择New->Navigation Resource File,在File name反面输入文件名:nav_host,选择Resource type为Navigation,点击ok即可创建Navigation graph资源文件:nav_host.xml
3)、把新建的Fragment引入到该资源文件内:

按照上面截图的顺序,在上面第二步创建的nav_host.xml文件内里依次操纵。在标记有3的搜索框处搜索要添加的Fragment,然后从Design模式切换到Split模式,在内里编辑功能:跳转的顺序、action行为运动细节等。最终代码如下:
  1.                                                                                                                                    
复制代码
argument
类似于Activity的跳转传参,只不外传参取参更加方便简单,如果某个Fragment要吸收从别的Fragment传过来的参数,那么可以通过argument标签处理处罚,如果我们在kotlin代码内里没有传参,那么我们获取到的就是通过argument标签设定的默认值,详细如下:
  1. //传值且跳转val flowStepNumberArg=1val action = HomeFragmentDirections.nextAction(flowStepNumberArg)findNavController().navigate(action)//取值val safeArgs: FlowStepFragmentArgs by navArgs()val flowStepNumber = safeArgs.flowStepNumber
复制代码
5、创建menu菜单:bottom_nav_menu.xml

  1.                                        
复制代码
注意:
这里的item.id和Navigation graph资源文件中的fragment.id必须保持一致,否则,恭喜入坑。
6、最后是Fragment的寄主NavigationPrimaryActivity和activity_navigation_primary.xml的处理处罚:

  1.                                                             
复制代码
上面fragment标签的id在Activity内里将会用到,这一点要特别注意,别的注意事项以及说明,代码内里表明的很清楚了。
接下来就是Activity内里的逻辑处理处罚,一共分四步
  1. class NavigationPrimaryActivity : BaseActivity() {            override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_navigation_primary)                //第一步获取到NavHostFragment,这里的nav_fragment就是本Activity对应的xml内里Fragment标签的id。        val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.nav_fragment) as NavHostFragment? ?: return                //第二步获取到NavController,这一步的内容险些都是死的。        val navController = host.navController                //第三步设置BottomNavigationView,这里的bottom_nav_view就是Activity对应的xml内里BottomNavigationView控件的id。        val bottomNav = findViewById(R.id.bottom_nav_view)        //这里,将导航控件BottomNavigationView与navController关联起来。        bottomNav?.setupWithNavController(navController)                //第四步添加路由监听,这一步的内容险些都是死的。        navController.addOnDestinationChangedListener { _, destination, _ ->            val dest: String = try {                       resources.getResourceName(destination.id)               } catch (e: Resources.NotFoundException) {                destination.id.toString()            }            toast("Navigated to $dest")        }    }}
复制代码
要注意一个细节:
第三部实在分两个细节,一是初始化BottomNavigationView的id,二是将导航控件BottomNavigationView与navController关联起来。运行效果如下:



7、跳转传参

虽然Fragment之间通报参数的几率比力低,但是多少照旧会用到。
1)、无参跳转

在HomeFragment中的onViewCreated(view: View, savedInstanceState: Bundle?)函数中添加以下代码:
  1. //此中,id值action_homeFragment_to_oneFragment是我们在nav_host.xml资源内添加的action属性。//这里是界说了一个无参跳转:homeFragment_to_oneFragmentopen1.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_homeFragment_to_oneFragment))
复制代码
上面界说了一个从homeFragment跳转到oneFragment的动作。
此中R.id. action_homeFragment_to_oneFragment是我们在nav_host资源内添加的action属性的id
R.id. action_homeFragment_to_oneFragment中:
action:意指运动;
homeFragment_to_oneFragment:从homeFragment到oneFragment
2)、带参跳转

这个现在尚未研究乐成,无法编译生成带参跳转的重载方法,待反面乐成了在完成这部分内容。
最厥后说一个关于带参跳转的问题的办理方案,问题如下:
  1. Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option.
复制代码
  1. android {    ......    compileOptions {                    sourceCompatibility = 1.8                    targetCompatibility = 1.8        }        kotlinOptions {                    jvmTarget = "1.8"        }}
复制代码
添加上面加粗标红的代码。然后按下图操纵即可完成:


来源:https://blog.csdn.net/haoyuegongzi/article/details/112008201
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )