【安卓笔记】—— 页面导航 Navigation(3)
ViewModel、LiveData、DataBinding 和 Navigation的 结合
- 搭建界面
- 创建 ViewModel
- DataBinding 绑定数据
ViewModel 核心作用:管理 Activity 中的数据
使用 ViewModel 管理 Navigation 导航当中的数据,可以实现切换页面数据不丢失,架构更加清晰
关于安卓搭建界面:是用图形化方式还是用代码:ConstraintLayout 布局的出现,使得图形化方式搭建界面变得十分便利。而在以前,ConstraintLayout出现之前,往往使用的是 RelativeLayout,使用图形化界面不方便,所以更倾向于用代码写界面。现在,利用图形化方式搭建界面是十分直观与方便的,建议使用图形化方式,没有必要再用代码写界面了。
搭建界面
首先创建两个 Fragment ,我们将实现 Home 切换到 Detail
搭建 Home 页面:
搭建 Detail 页面:
连接 Home 与 Detail 的逻辑图:
在 activity_main.xml 中,放入 NavHostFragment
界面搭建完成,接下来是完善代码部分。
创建 ViewModel
创建一个继承自 View 的类 MyViewModel:
在 ViewModel 中管理一个变量 num:
public class MyViewModel extends ViewModel {private MutableLiveData<Integer> num; public MutableLiveData<Integer> getNum(){if(num == null){ // 不存则创建一个,初值为 0num = new MutableLiveData<>();num.setValue(0);}return num;}public void add(int x){num.setValue(num.getValue() + x);if(num.getValue() < 0){ // 数字不能 < 0num.setValue(0);}}
}
DataBinding 绑定数据
要使用 DataBinding ,需要在 build.gradle(Module:app) 下,android 的 defaultConfig 下添加一句话:
dataBinding.enabled true
然后去 home 界面的 xml 中,将布局转化成 data binding 布局
然后在 xml 中设置变量(variable) data,获取 MyViewModel 中的变量
<data><variablename="data"type="com.example.navviewmodel.MyViewModel" />
</data>
将 MyViewModel 中的变量绑定到 Home 界面的 TextView上:
android:text="@{String.valueOf(data.getNum())}"
关于按键的动作绑定(例如Button的OnClick()):一般与数据相关则通过DataBinding 绑定到界面上,与数据无关而仅与逻辑相关(例如界面跳转)一般在 Activity 或 Fragment 中写代码。
来到 HomeFragment.java :
编写 Button 动作,在导航控制器跳转页面时,无需像之前一样利用 bundle 存储数据,由于利用了 ViewModel 管理变量,只需跳转页面即可。
public View onCreateView(LayoutInflater inflater, final ViewGroup container,Bundle savedInstanceState) {final MyViewModel myViewModel;myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);final FragmentHomeBinding binding;binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home,container, false);binding.setData(myViewModel);binding.setLifecycleOwner(getActivity());binding.button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {NavController controller = Navigation.findNavController(view); // 获取导航控制器controller.navigate(R.id.action_homeFragment_to_detailFragment); // Home -> Detail}});binding.seekBar.setProgress(myViewModel.getNum().getValue()); // 初始化进度条,使得数据不丢失binding.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int i, boolean b) { // 滑动进度条时myViewModel.getNum().setValue(i); // 将进度条的数字赋给 num}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}});return binding.getRoot();}
同理,来到 DetailFragment.java:
设置变量(variable) data,获取 MyViewModel 中的变量的
<data><variablename="data"type="com.example.navviewmodel.MyViewModel" />
</data>
将 MyViewModel 中的变量绑定到 Detail 界面的 TextView上:
由于 Detail 界面的 “+” 与 “-” 按键动作与数据相关,因此通过DataBinding 绑定到界面上:
Button " - " 实现了数据 -1,添加如下代码:
android:onClick="@{()->data.add(-1)}"
Button " + " 实现了数据 +1,添加如下代码:
android:onClick="@{()->data.add(+1)}"
而“返回按钮”与数据无关,因此在 DetailFragment.java 中写代码:
public View onCreateView(LayoutInflater inflater, final ViewGroup container,Bundle savedInstanceState) {MyViewModel myViewModel;myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);FragmentDetailBinding binding;binding = DataBindingUtil.inflate(inflater, R.layout.fragment_detail, container, false);binding.setData(myViewModel);binding.setLifecycleOwner(getActivity());binding.button4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {NavController controller = Navigation.findNavController(view);controller.navigate(R.id.action_detailFragment_to_homeFragment2);}});return binding.getRoot();}
至此,功能全部写完,
运行效果如下:
滑动进度条,显示数字;
点击进入,切换页面;
点击+,数字变大;
点击返回,切换回初始界面。
【安卓笔记】—— 页面导航 Navigation(3)相关推荐
- 【安卓笔记】—— 页面导航 Navigation(2)
Navigation 中的数据传递和过渡动画 创建一个简单的页面导航 传递静态数据 传递动态数据 自定义动画 transalate:移动 scale:缩放 rotate:旋转 创建一个简单的页面导航 ...
- 小牛的安卓笔记-----底部导航栏的实现以及用TabLayout+ViewPager+Fragment实现页面滑动切换
昨夜西风凋碧树,独上高楼,望尽天涯路. 今天难得有时间,准备写一写我们在APP中经常用到的页面形式,废话不多说,直接一张图看看页面效果你就知道为啥是常用的页面形式.先看看逻辑和最后的效果是怎么样的: ...
- WinPhone学习笔记(一)——页面导航与页面相关
最近学一下Windows Phone(接下来简称"WinPhone")的开发,在很久很久前稍探究一下WinPhone中对一些传感器的开发,那么现在就从头来学学WinPhone的开发 ...
- 微信小程序 小程序生命周期、页面导航/事件、WXS脚本(笔记)
文章目录 1. 页面导航 1.1 声明式导航 1.2 编程式导航 1.3 导航传参 2. 页面事件 3. 生命周期 3.1 应用生命周期 3.2 页面生命周期 4. WXS脚本 4.1 什么是WXS ...
- 第二十四章:页面导航(五)
导航变化 当您尝试使用ModalEnforcement和MvvmEnforcement程序时,您可能会对模态页面未能保留任何信息感到不安.我们都遇到了导航到用于输入信息的页面的程序和网站,但是当您离开 ...
- windows phone 学习之页面导航和数据传递
创建一个windows phone 应用程序,在xaml文件里添加三个按钮和三个textblock,添加一个windows phone 页面(命名为SecondPage),同样也是添加三个按钮和三个t ...
- windows phone 页面导航(6)
页面导航的例子我们使用的是两个页面,从第一个页面(MainPage)导航到第二个页面(SecondPage),然后可以从第二个页面导航到第一个页面 ,使用的os 7.1: 页面导航没有引入新的命名空间 ...
- 页面导航【WP7学习札记之七】
本节是WP7学习札记的第七篇,讲述的内容摘要主要是将页面导航的两种方式.地址别名.页面之间的数据传递(包括传递字符串.和传递对象两种方式).回退按钮(重写Back键的事件),具体如下: 首先讲述下Wi ...
- jsf 导航_JSF页面导航示例教程
jsf 导航 Page navigation is the redirection of a page based on the events performed for instance – on ...
最新文章
- 11岁姑娘挑战8分钟编程小程序!蚂蚁金服董事长井贤栋:欢迎加入
- 阿里笔试题—战报交流
- jQuery入门学习
- 时间处理总结(二)oracle
- pomelo获取客户端IP
- monterey系统怎么降级?macOS Monterey系统降回Big Sur的详细教程
- 嗨淘V12刷任务点赞系统源码手动派单版本
- 4G通信技术LTE介绍
- 人人都需要专利的原因
- python实现Longest Common Subsequence最长公共子序列算法
- 选择、冒泡、插入、快速排序
- 小程序Git版本管理
- 如何免费的、完整的把 PDF 转换为 Word?
- Aurora 64B66B IP核的硬件跑通
- ZYNQ产品生产拷机问题思考
- 【MySQL】连接查询
- icloud 照片同步_如何在线查看iCloud照片
- 选对Shopee货代对店铺影响有多大?星卓越货代系统为您分析
- ocr扫描识别软件操作步骤
- shell之未找到命令