当前位置: 首页 > news >正文

静安网站建设关键词优化seo农村自建房设计图120平方米三层

静安网站建设关键词优化seo,农村自建房设计图120平方米三层,完整的社群营销方案,企业网站组网方案写在前面 Google在2018年就推出了Jetpack组件库#xff0c;但是直到今天我才给重视起来#xff0c;这真的不得不说是一件让人遗憾的事。过去几年的空闲时间里#xff0c;我一直在尝试做一套自己的组件库#xff0c;帮助自己快速开发#xff0c;虽然也听说过Jetpack#…写在前面 Google在2018年就推出了Jetpack组件库但是直到今天我才给重视起来这真的不得不说是一件让人遗憾的事。过去几年的空闲时间里我一直在尝试做一套自己的组件库帮助自己快速开发虽然也听说过Jetpack但是压根儿也没去了解但是其实自己已经无形之中用到过很多Jetpack中的库了只是自己不知道比如说databinding、viewmodel、camerax等等 所以我打算推出一个Jetpack的学习记录今天是第一个组件Navigation 老规矩文末有demo的源码永久0积分 demo效果 正文 关于Navigation 据通义千问的说法 Android Jetpack Navigation组件是Google推出的一个用于简化Android应用导航的库。旨在提供一种结构化和统一的方式来管理应用程序中的屏幕切换和导航流程特别是对于基于Fragment的应用。 关于Navigation我觉得可能大家在生活里对于它的功能并不会陌生拿微信来说底部有四个按钮分别是“微信”、“通讯录”、“发现”、“我”如下图 当我们分别点击四个按钮的时候界面区域也会随之切换到对应的页面。这就是一种比较常见的底部导航功能。当然这种结合底部导航栏的fragment切换只是Navigation能够实现的其中一种还有其他的并不需要底部导航栏的比如说登录模块登录模块可能包含着登录、注册和重置密码这三个子模块那么按照UI的设计就需要三张页面去实现我们知道可以使用一个Activity去嵌套三个Fragment去实现那么显然这种纯fragment切换这也是Navigation可以实现的范畴 整体设计思路 今天展示Navigation的使用的demo的整体设计思路为LoginActivityMainActivity 其中LoginActivity包含着LoginFragment、RegisterFragment、ResetPasswordFragment 其中MainActivity包含HomeFragment、ContactFragment、FindFragment、MeFragment 编码开始 我的环境AndroidStudio 4.2.2 1引用 项目级build.gradle dependencies {...classpath androidx.navigation:navigation-safe-args-gradle-plugin:2.5.0...} 模块级build.gradle plugins {....id androidx.navigation.safeargs.kotlin }dependencies {...//Navigationimplementation androidx.navigation:navigation-fragment-ktx:2.4.2implementation androidx.navigation:navigation-ui-ktx:2.4.2 } 2创建导航文件 步骤如下 按照这样的步骤即可创建login_nav_graph.xml和main_nav_graph.xml两个导航文件如图 此时两份文件里内容还是空的具体内容还需要自行添加 AndroidStudio支持可视化添加fragment以及相互之间的导航关系这点真的是非常方便 1. 点击加号可以添加fragment到导航文件 我们首先把使用到的fragment全部添加到导航文件中如下图 这里先看一下AndroidStudio自动为我们生成的代码 fragmentandroid:idid/loginFragmentandroid:namecom.swy.navigationdemo.login.LoginFragmentandroid:labelfragment_logintools:layoutlayout/fragment_login / 这个fragment标签与我们拖进来的三个fragment是一一对应的它包含了四个参数 id比唯一标识符可供本文件其他地方调用name是对应Fragment的路径label是对应Fragment的一个标签tools:layout对应Fragment的布局文件 还有另一个属性也是值得关注的就是最外层navigation标签的 app:startDestinationid/loginFragment 这表明了在LoginActivity中默认优先显示的是LoginFragment 说明我们首次添加的Fragment会被默认为优先显示的Fragment即如果我这里优先添加LoginFragment到导航图navigation自动生成app:startDestinationid/loginFragment那么如果我首先把RegisterFragment添加进导航图那么这个属性就会是app:startDestinationid/registerFragment 2.增加Fragment间的导航关系  点LoginFragment框体右边中部会出现一个圆环 点击该圆环并拖动就会出现一条蓝线将该蓝线指向RegisterFragment后松手 此时就会看到LoginFragment到RegisterFragment的导航关系被建立了观察新增的action代码 actionandroid:idid/action_loginFragment_to_registerFragmentapp:destinationid/registerFragment / id唯一标识符可供Activity调用destination用来表示跳转的目的地可见此时这个action表示的是跳转到registerFragment。需要说明的是这个跳转每次都会新建实例也就是我可以从LoginFragment跳转到LoginFragment但是这两个LoginFragment是不同的实例也就是栈内会同时存在两个不同的LoginFragment。 其他的属性 app:launchSingleTop类似于Android活动中singleTop启动模式当该属性为true时如果目标Fragment已经在回退栈的顶部即用户最近访问的Fragment那么Navigation组件将不会创建新的Fragment实例而是重用已经存在的那个Fragment实例。如果目标Fragment已经在回退栈中但不在栈顶那么app:launchSingleTop属性将不会起作用。在这种情况下即使app:launchSingleTop设置为trueNavigation组件也会创建一个新的目标Fragment实例并将其推送到回退栈的顶部。app:popUpTo出栈直到某个元素。比如目前栈内有fragment1 - fragment2 - fragment3当我在fragment4中定义了app:popUpTo:id/fragment1时那么fragment2和fragment3会被出栈最终栈内情况为fragment1 - fragment4。app:popUpToInclusive这个属性是配合上面的app:popUpTo使用的用来判断到达指定元素时是否把指定元素也出栈。还是以上面的例子来说明如果该值为true那么作为指定元素fragment1也会被出栈最终栈内只剩下fragment4.app:enterAnim、app:exitAnim、app:popEnterAnim、app:popExitAnim这四个属性都是跳转动画相关的前两个用来配置移动到目的地的动画后两个配置离开目的地的动画。 举例说明fragment1跳转到fragment2 1enterAnim和exitAnim发生于fragment1跳转到fragment2的过程中 enterAnim是fragment2的入场动画、exitAnim是fragment1的离场动画 2popEnterAnim和popExitAnim发生于fragment2返回到fragment1的过程中 popEnterAnim为返回发生后fragment1的入场动画 popExitAnim为返回时fragment2的离场动画 按照我们最开始设计的跳转关系去完成导航文件最终是这样的 即默认展示登录页面登录页面可以跳转到注册页面或者是重置密码页面同时在注册页面和重置密码页面也可以返回到登陆页面 同理我们完成main_nav_graph的导航关系如下 因为我们仿照的是微信的底部导航栏home、contact、find、me四个fragment其实是平级的它们之间并不存在导航关系。当然我们也可以根据自己的实际业务使用不同的action来设计不同维度和复杂度的导航关系。  至此导航文件也有了剩下的就是创建一个支持导航关系的容器了 3导航主机 以LoginActivity为例 布局文件 ?xml version1.0 encodingutf-8? androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.LoginActivityandroidx.fragment.app.FragmentContainerViewandroid:idid/login_nav_host_fragmentandroid:nameandroidx.navigation.fragment.NavHostFragmentandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentapp:defaultNavHosttrueapp:navGraphnavigation/login_nav_graphapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparent //androidx.constraintlayout.widget.ConstraintLayout 创建FragmentContainerView作为导航主机Navigation Host这里有几个地方需要说明 android:nameandroidx.navigation.fragment.NavHostFragment是固定的写法 app:defaultNavHost的作用是将该FragmentContainerView标记为默认的导航主机这意味着这个FragmentContainerView会拦截系统的后退按钮事件。当用户点击后退按钮时Navigation组件会按照导航图中的历史记录进行后退操作而不是直接关闭Activity。并且在一个Activity中通常只需要一个NavHostFragment作为导航主机。设置app:defaultNavHosttrue可以确保只有这一个NavHostFragment响应导航操作和后退按钮事件避免多个NavHostFragment之间的冲突。 app:navGraph是将导航文件与导航主机相关联 LoginActivity class LoginActivity : AppCompatActivity() {private lateinit var binding: ActivityLoginBindingprivate lateinit var navController:NavControlleroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding ActivityLoginBinding.inflate(layoutInflater)setContentView(binding.root)val navHostFragment supportFragmentManager.findFragmentById(R.id.login_nav_host_fragment) as NavHostFragmentnavController navHostFragment.navController}public fun getNavController(): NavController {return navController}override fun onSupportNavigateUp(): Boolean {return findNavController(R.id.login_nav_host_fragment).navigateUp()} } 核心代码获取NavController 说明这里声明了一个方法将获取到的navController返回了出去主要是供Fragment中进行调用因为这里Activity只是容器具体的UI交互是在对应的Fragment上面的以LoginFragment为例 class LoginFragment : Fragment() {private lateinit var binding: FragmentLoginBindingprivate lateinit var navController: NavControlleroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {binding FragmentLoginBinding.inflate(layoutInflater)val activity requireActivity() as LoginActivitynavController activity.getNavController()initListener()return binding.root}private fun initListener() {binding.login.setOnClickListener {val intent Intent(activity, MainActivity::class.java)startActivity(intent)}binding.register.setOnClickListener {navController.navigate(R.id.action_loginFragment_to_resetPasswordFragment)}binding.reset.setOnClickListener {navController.navigate(R.id.action_loginFragment_to_resetPasswordFragment)}}} 通过这两行代码fragment获取到了activity的navcontroller val activity requireActivity() as LoginActivitynavController activity.getNavController() 之后就可以操作导航事件了如下 binding.register.setOnClickListener {navController.navigate(R.id.action_loginFragment_to_resetPasswordFragment)}binding.reset.setOnClickListener {navController.navigate(R.id.action_loginFragment_to_resetPasswordFragment)} 说明这里面的 R.id.action_loginFragment_to_resetPasswordFragment 和 R.id.action_loginFragment_to_resetPasswordFragment 就是login_nav_graph.xml文件中定义的两个action的id 我相信写到这里你基本上就能够看出来整个的调用机制了 4NavigationBottomNavigationView实现底部导航 上面讲了普通的fragment切换那么关于带底部导航栏的切换也还是很有必要说明以下的 主界面布局 ?xml version1.0 encodingutf-8? androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.MainActivityandroidx.fragment.app.FragmentContainerViewandroid:idid/main_nav_host_fragmentandroid:nameandroidx.navigation.fragment.NavHostFragmentandroid:layout_width0dpandroid:layout_height0dpapp:defaultNavHosttrueapp:layout_constraintBottom_toTopOfid/bottomNavigationViewapp:layout_constraintEnd_toEndOfparentapp:layout_constraintHorizontal_bias0.0app:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparentapp:layout_constraintVertical_bias0.0app:navGraphnavigation/main_nav_graph /com.google.android.material.bottomnavigation.BottomNavigationViewandroid:idid/bottomNavigationViewandroid:layout_widthmatch_parentandroid:layout_height60dpapp:menumenu/main_menuapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparent //androidx.constraintlayout.widget.ConstraintLayout 显然页面中只是增加了BottomNavigationView对应的UI结构如下 说明 我这里使用了menu来实现了底部导航栏的几个item内容的导入代码如下 ?xml version1.0 encodingutf-8? menu xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoitemandroid:idid/homeFragmentandroid:iconmipmap/messageandroid:title首页app:showAsActionifRoom /itemandroid:idid/contactFragmentandroid:iconmipmap/contactandroid:title联系人app:showAsActionifRoom /itemandroid:idid/findFragmentandroid:iconmipmap/findandroid:title发现app:showAsActionifRoom /itemandroid:idid/meFragmentandroid:iconmipmap/meandroid:title我app:showAsActionifRoom / /menu 重点说明这里面四个item的id并不是随意定义的一定要与main_nav_graph.xml文件中对应的几个fragment的id保持一致否则点击底部导航栏的按钮是无法触发对应的fragment切换的如下 这里面只是UI上对应了如何让bottomnavigationview与navcontroller也关联到一起呢 MainActivity.class class MainActivity : AppCompatActivity() {private lateinit var binding:ActivityMainBindingprivate lateinit var navController: NavControlleroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)val navHostFragment supportFragmentManager.findFragmentById(R.id.main_nav_host_fragment) as NavHostFragmentnavController navHostFragment.navControllerbinding.bottomNavigationView.setupWithNavController(navController)}override fun onSupportNavigateUp(): Boolean {return findNavController(R.id.main_nav_host_fragment).navigateUp()}} 核心代码就是这一句了 binding.bottomNavigationView.setupWithNavController(navController) 补充内容 Fragment间数据通信的两种方式 先看效果 说明 LoginFragment跳转到RegisterFragment使用SafeArgs方式 LoginFragment跳转到ResetpasswordFragment使用Bundle方式  1SafeArgs推荐 Android官方推荐使用Safe Args来实现Fragment间数据通信原因主要包括以下几个方面 类型安全 Safe Args提供了类型安全的方式来传递参数。在navigation graph XML文件中定义的每个参数都有明确的数据类型例如字符串、整数、布尔值等。这将自动为这些参数生成对应的Args类并提供get和set方法从而确保在编译时就能捕获到类型不匹配的问题而不是在运行时才出现崩溃。 清晰性与可读性 在navigation graph中直接指定参数及其类型使得整个应用导航结构更加清晰。通过查看XML文件开发者可以很容易地了解哪些参数在Fragment之间传递以及它们的类型是什么。 减少代码量和错误 使用Safe Args不需要手动创建和解析Bundle对象来传递数据这大大减少了出错的可能性。自动生成的Args类简化了参数传递过程使得开发者可以直接操作对象而非键值对提高了编码效率。 生命周期感知 Safe Args配合Navigation组件一起使用时能够更好地适应Android组件的生命周期变化。即使目标Fragment因为配置更改如屏幕旋转而重新创建传递的参数也能得到妥善保存和恢复。 易于维护 随着项目规模的增长Safe Args能帮助保持代码的整洁和组织有序。当需要修改或添加新的参数时只需要在navigation graph文件中更新即可同时会自动反映到相关的Args类中无需在多个地方手动同步修改。 具体的使用过程如下 1.引用插件 项目级build.gradle buildscript {...dependencies {...classpath androidx.navigation:navigation-safe-args-gradle-plugin:2.5.3} } 模块级build.gradle plugins {...id androidx.navigation.safeargs.kotlin } 引用完成之后Sync项目Rebuild项目 2.实际使用修改login_nav_graph.xml文件增加argument参数 fragmentandroid:idid/loginFragmentandroid:namecom.swy.navigationdemo.login.LoginFragmentandroid:labelfragment_logintools:layoutlayout/fragment_loginactionandroid:idid/action_loginFragment_to_registerFragmentapp:destinationid/registerFragmentargumentandroid:namedata1app:argTypestringandroid:defaultValue//actionactionandroid:idid/action_loginFragment_to_resetPasswordFragmentapp:destinationid/resetPasswordFragment/action/fragment 说明我在自己环境上调试的时候发现我定义的argument属性在定义name的时候总是会提示xxx is not a valid destination for tag argument这样的错误网上也没有找到相关的解释和解决方法但是经过实际测试这个地方报红并不影响使用如图 LoginFragment.java binding.register.setOnClickListener {val data1 这是使用safe args方式从登录界面传递的数据navController.navigate(LoginFragmentDirections.actionLoginFragmentToRegisterFragment(data1))} RegisterFragment.java val data1 arguments?.getString(data1) binding.textData1.text data1 说明 上面展示的是单一参数多参数也是支持的如下 比如这里我又增加了一个data3那么在LoginFragment中使用逗号隔开两个参数即可如下 binding.register.setOnClickListener {val data1 这是使用safe args方式从登录界面传递的数据val data3 data3navController.navigate(LoginFragmentDirections.actionLoginFragmentToRegisterFragment(data1,data3))} RegisterFragment val data1 arguments?.getString(data1) val data3 arguments?.getString(data3) binding.textData1.text data1data3 最终的效果  可见 上面说的safeargs的优点确实是做到了易于维护 易于维护 随着项目规模的增长Safe Args能帮助保持代码的整洁和组织有序。当需要修改或添加新的参数时只需要在navigation graph文件中更新即可同时会自动反映到相关的Args类中无需在多个地方手动同步修改。 2Bundle LoginFragment binding.reset.setOnClickListener {val data2 这是使用普通Bundle方式从登录界面传递的数据val bundle Bundle();bundle.putString(data2,data2)navController.navigate(R.id.action_loginFragment_to_resetPasswordFragment,bundle)} ResetPasswordFragment val bundle arguments val data2 bundle?.getString(data2) binding.textData2.text data2 至此Navigation fragment间数据通信的两种方式的简单介绍就结束了 说明关于safeargs的使用前面讲解的并不是全部的实现方式只是其中的一种就比如我这里从LoginFragment跳转到RegisterFragment我的argument是在LoginFragment里面定义的我看网上还有讲解的是也可以在RegisterFragment里面定义包括Bundle也可以与argument属性有联动关系等等之类的吧大家有兴趣可以都了解一下 到目前为止简单的demo算是初具雏形源码如下 demo 源码
http://www.w-s-a.com/news/156294/

相关文章:

  • 厦门网站建设680元好男人的最好的影院
  • 石家庄网站建设设计产品设计专业就业前景
  • 网站移动排名做最好最全的命理网站
  • 网站怎么防黑客杭州市做外贸网站的公司
  • 网站推广公司认准乐云seo易语言做网站登录
  • 配色设计网站推荐网站下拉菜单重叠
  • 内容展示型网站特点在北京注册公司需要多少钱
  • h5网站源代码创意设计理念
  • 岳阳网站开发服务推广运营平台
  • 网站开发得多长时间湖南建设人力资源网证书查询
  • 论坛网站开发网络营销是什么时候产生的
  • 帮人做网站赚钱无忧软文网
  • 做网站要不要营业执照重庆网站优化seo公司
  • 学院宣传网站建设简介做网站没灵感
  • 网站建设终稿确认书网站意义学校
  • 3小时网站建设平台专业制作教学课件
  • 曲阜网站建设百度开户现货黄金什么网站可以做直播
  • 比较好的企业建站平台小程序开发外包该注意些什么
  • 建行官网官网网站吗二次元风格wordpress模板
  • 怎样开通自己的网站网址导航哪个主页最好
  • 大良o2o网站建设详情页设计说明怎么写
  • 您与此网站之间建立的连接不安全汽车cms系统是什么意思
  • 有没有做logo的网站企业网站的内容营销
  • 哈尔滨做企业网站怎么做网站自动响应
  • 网站建设硬件和软件技术环境配置签约做网站模板
  • 教育网站建设的素材手机app制作流程
  • 免费行情软件网站大全下载网站备案查询
  • flex网站模板wordpress实时预览
  • 建设银行网站模板为什么企业要建设自己的企业文化
  • 网站建设必知免费手机网站建站系统