Android通过ViewModel保存数据实现多页面的数据共享功能
程序员文章站
2022-06-20 14:48:51
通过viewmodel实现的数据共享符合android的mvc设计模式,将数据独立出来
实现的demo
1、主页面通过seekbar 来改变数字的值
2、点击进入就进入第二个...
通过viewmodel实现的数据共享符合android的mvc设计模式,将数据独立出来
实现的demo
1、主页面通过seekbar 来改变数字的值
2、点击进入就进入第二个界面,但是数据还是共享的
3、随便加两个数字上去,再次切换
4、发现数据还是共享的
下面是具体实现步骤:
1、建立两个fragment(使用了binding 和 navigation)
一点要添加binding 和 navigation 不然做不了
2、建立一个继承于viewmodel的类
3、分别在两个fragment的代码中使用继承于viewmodel的那个类,就可以实现数据共享
下面是具体代码:
1、继承于viewmodel的类
package com.example.naviation01; import androidx.lifecycle.mutablelivedata; import androidx.lifecycle.viewmodel; public class myviewmode extends viewmodel { private mutablelivedata<integer> number; public mutablelivedata<integer> getnumber(){ if(this.number == null){ this.number = new mutablelivedata<>(); this.number.setvalue(0); } return this.number; } public void add(int x){ this.number.setvalue(this.number.getvalue()+x); if(this.number.getvalue() < 0){ this.number.setvalue(0); } } }
2、fragment 主页
package com.example.naviation01; import android.os.bundle; import androidx.databinding.databindingutil; import androidx.fragment.app.fragment; import androidx.fragment.app.fragmentcontroller; import androidx.lifecycle.viewmodel; import androidx.lifecycle.viewmodelprovider; import androidx.lifecycle.viewmodelproviders; import androidx.navigation.navcontroller; import androidx.navigation.navigation; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.seekbar; import com.example.naviation01.databinding.fragmenthomebinding; /** * a simple {@link fragment} subclass. */ public class homefragment extends fragment { public homefragment() { // required empty public constructor } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate the layout for this fragment final myviewmode myviewmode; myviewmode = viewmodelproviders.of(getactivity()).get(myviewmode.class); fragmenthomebinding binding; binding = databindingutil.inflate(inflater,r.layout.fragment_home,container,false); binding.setdata(myviewmode); binding.setlifecycleowner(getactivity()); binding.seekbar.setprogress(myviewmode.getnumber().getvalue()); binding.seekbar.setonseekbarchangelistener(new seekbar.onseekbarchangelistener() { @override public void onprogresschanged(seekbar seekbar, int progress, boolean fromuser) { myviewmode.getnumber().setvalue(progress); } @override public void onstarttrackingtouch(seekbar seekbar) { } @override public void onstoptrackingtouch(seekbar seekbar) { } }); binding.button.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { navcontroller controller = navigation.findnavcontroller(v); controller.navigate(r.id.action_homefragment_to_detailfragment); } }); return binding.getroot(); //return inflater.inflate(r.layout.fragment_home, container, false); } }
xml
<?xml version="1.0" encoding="utf-8"?> <layout 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"> <data> <variable name="data" type="com.example.naviation01.myviewmode" /> </data> <framelayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".homefragment"> <androidx.constraintlayout.widget.constraintlayout android:layout_width="match_parent" android:layout_height="match_parent"> <textview android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@{string.valueof(data.number)}" android:textsize="30sp" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.255" /> <seekbar android:id="@+id/seekbar" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constrainthorizontal_bias="0.0" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.456" /> <button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@string/function01" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constrainthorizontal_bias="0.498" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.679" /> </androidx.constraintlayout.widget.constraintlayout> </framelayout> </layout>
3、fragment 副页
package com.example.naviation01; import android.os.bundle; import androidx.databinding.databindingutil; import androidx.fragment.app.fragment; import androidx.lifecycle.viewmodelproviders; import androidx.navigation.navcontroller; import androidx.navigation.navigation; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import com.example.naviation01.databinding.fragmentdetailbinding; /** * a simple {@link fragment} subclass. */ public class detailfragment extends fragment { public detailfragment() { // required empty public constructor } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate the layout for this fragment myviewmode myviewmode; myviewmode = viewmodelproviders.of(getactivity()).get(myviewmode.class); fragmentdetailbinding binding; binding = databindingutil.inflate(inflater,r.layout.fragment_detail,container,false); binding.setdate(myviewmode); binding.setlifecycleowner(getactivity()); binding.button4.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { navcontroller controller = navigation.findnavcontroller(v); controller.navigate(r.id.action_detailfragment_to_homefragment); } }); return binding.getroot(); //return inflater.inflate(r.layout.fragment_detail, container, false); } }
xml
<?xml version="1.0" encoding="utf-8"?> <layout 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"> <data> <variable name="date" type="com.example.naviation01.myviewmode" /> </data> <framelayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".detailfragment"> <androidx.constraintlayout.widget.constraintlayout android:layout_width="match_parent" android:layout_height="match_parent"> <textview android:id="@+id/textview3" android:layout_width="131dp" android:layout_height="55dp" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@{string.valueof(date.number)}" android:textsize="30sp" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.23" /> <button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@string/function02" android:onclick="@{()->date.add(1)}" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constrainthorizontal_bias="0.104" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.499" /> <button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@string/function03" android:onclick="@{()->date.add(-1)}" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constrainthorizontal_bias="0.899" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.499" /> <button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginstart="8dp" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" android:text="@string/function04" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constrainthorizontal_bias="0.498" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:layout_constraintvertical_bias="0.664" /> </androidx.constraintlayout.widget.constraintlayout> </framelayout> </layout>
4、xml main_activity
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.constraintlayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".mainactivity"> <fragment android:id="@+id/fragment" android:name="androidx.navigation.fragment.navhostfragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margintop="8dp" android:layout_marginend="8dp" android:layout_marginbottom="8dp" app:defaultnavhost="true" app:layout_constraintbottom_tobottomof="parent" app:layout_constraintend_toendof="parent" app:layout_constraintstart_tostartof="parent" app:layout_constrainttop_totopof="parent" app:navgraph="@navigation/nav_graph" /> </androidx.constraintlayout.widget.constraintlayout>
总结
以上所述是小编给大家介绍的android通过viewmodel保存数据实现多页面的数据共享功能,希望对大家有所帮助