Android通过ViewModel保存数据实现多页面的数据共享功能

通过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保存数据实现多页面的数据共享功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Android开发中ViewPager实现多页面切换效果

    ViewPager用于实现多页面的切换效果,该类存在于Google的兼容包里面,所以在引用时记得在BuilldPath中加入"Android-support-v4.jar" 首先必须知道:要使用ViewPager,必须要使用PagerAdapter为其提供数据,也就必须实现下面四个方法: 1, getCount():ViewPager需要显示的页面个数 2,isViewFromObject(View view, Object object):view 是某个位置的页面,Object是

  • Android数据共享 sharedPreferences 的使用方法

    Android数据共享 sharedPreferences 的使用方法 Android 中通过 sharedPreferences 来持久化存储数据并进行共享 在 Activity 或存在 Context 环境中即可使用 context.getSharedPreferences(name, Context.MODE_PRIVATE); 设置要保存的数据: mSp = context.getSharedPreferences(name, Context.MODE_PRIVATE); mEditor

  • Android编程实现ViewPager多页面滑动切换及动画效果的方法

    本文实例讲述了Android编程实现ViewPager多页面滑动切换及动画效果的方法.分享给大家供大家参考,具体如下: 一.首先,我们来看一下效果图,这是新浪微博的Tab滑动效果.我们可以手势滑动,也可以点击上面的头标进行切换.与此同方式, 白色横条会移动到相应的页卡头标下.这是一个动画效果,白条是缓慢滑动过去的.好了,接下来我们就来实现它. 二.在开始前,我们先要认识一个控件,ViewPager.它是google SDk中自带的一个附加包的一个类,可以用来实现屏幕间的切换. 这个附加包是and

  • Android应用中利用ViewPager实现多页面滑动切换效果示例

    1.添加android support包 因为上面的几个类都是在android support包中才提供,我们先添加包. 在Eclipse->Window->Android SDK Manager,选择列表中Extras->Android Support Library进行安装.下载完后在android-sdk\extras\android\support目录下,这里我们选择v4版本,进入v4目录,拷贝其中的android-support-v4.jar文件到工程的libs目录(若没有新建

  • Android通过ViewModel保存数据实现多页面的数据共享功能

    通过ViewModel实现的数据共享符合Android的MVC设计模式,将数据独立出来 实现的Demo 1.主页面通过SeekBar 来改变数字的值 2.点击进入就进入第二个界面,但是数据还是共享的 3.随便加两个数字上去,再次切换 4.发现数据还是共享的 下面是具体实现步骤: 1.建立两个Fragment(使用了Binding 和 Navigation) 一点要添加Binding 和 Navigation 不然做不了 2.建立一个继承于ViewModel的类 3.分别在两个Fragment的代

  • Android学习笔记-保存数据到SQL数据库中(Saving Data in SQL Databases)

    知识点: 1.使用SQL Helper创建数据库 2.数据的增删查改(PRDU:Put.Read.Delete.Update) 背景知识: 上篇文章学习了android保存文件,今天学习的是保存数据到SQL数据库中.相信大家对数据库都不陌生.对于大量重复的,有特定结构的数据的保存,用 SQL数据库 来保存是最理想不过了. 下面将用一个关于联系人的数据库Demo来具体学习. 具体知识: 1.定义Contract类 在创建SQL数据库之前,要创建Contract类.那什么是Contract类呢? 复

  • Android 实现永久保存数据的方法详解

    背景:在Android中按照数据保存的方式,可以分为如下几种Content Provider (用的SQLite实现),SQLite,SharedPreferences(用的XML实现),文件,网络等方式. 今天在项目中,需要做一个永久保存的数据,保存到本地.于是测试了这几种保存方式.其中:SharedPreferences.SQLite.Content Provider 会在[设置]--[应用管理]--点击[清除数据]的时候,会删除文件.所以不安全.文件系统:如果SD卡坏了,或者拔掉的时候也会

  • Android SharedPreferences实现保存登录数据功能

    本文实例为大家分享了Android SharedPreferences保存登录数据的具体代码,供大家参考,具体内容如下 目标效果: 程序运行显示一个登陆框,用户名输入admin,密码输入123456会提示登录成功,如果不是则提示不正确,如果勾选保存用户名,在下一个程序打开时,用户名会自动读取并显示. 1.activity_main.xml页面存放所有的控件,我在每一行都使用了线性布局. activity_main.xml页面: <RelativeLayout xmlns:android="

  • Android应用开发中数据的保存方式总结

    一.保存文件到手机内存 /** * 保存数据到手机rom的文件里面. * @param context 应用程序的上下文 提供环境 * @param name 用户名 * @param password 密码 * @throws Exception */ public static void saveToRom(Context context, String name , String password) throws Exception{ //File file = new File("/da

  • Android异步加载数据和图片的保存思路详解

    把从网络获取的图片数据保存在SD卡上, 先把权限都加上 网络权限 android.permission.INTERNET SD卡读写权限 android.permission.MOUNT_UNMOUNT_FILESYSTEMS android.permission.WRITE_EXTERNAL_STORAGE 总体布局 写界面,使用ListView,创建条目的布局文件,水平摆放的ImageView TextView 在activity中获取到ListView对象,调用setAdapter()方法

  • Android 使用 SharedPreferences 保存少量数据的实现代码

    1 SharedPreferences 介绍 SharedPreferences是使用键值对的方式来存储数据的 SharedPreferences share = getSharedPreferences("my_file", Context.MODE_PRIVATE); SharedPreferences.Editor editor = share.edit(); // 4 保存数据到文件 editor.putString("account", input_acc

  • Android 个人理财工具四:添加账单页面 下

    本文考虑把账单界面整理下,实现如下图中的功能.做之前感觉应该不难,但实际做时发现排列界面布局甚至比编写程序代码还要复杂.网上搜索发现,关于这种布局的资料能用的很少,Google Demo中用的最多的就是Listview了,但本实例的界面似乎要复杂一些. spinner和cursor如何配合使用成了完成此实例过程中的难点,本来应该很简单,但却把我郁闷坏了. 先给大家贴上最终的效果图片: 界面的xml: XML/HTML代码 <?xml version="1.0" encoding=

  • 浅析Android手机卫士保存手机安全号码

    推荐阅读: 浅析Android手机卫士sim卡绑定 深入浅析Android手机卫士保存密码时进行md5加密 详解Android 手机卫士设置向导页面 浅析Android手机卫士关闭自动更新 浅析Android手机卫士自定义控件的属性 浅析Android手机卫士读取联系人 调用ListView对象的setOnItemClickListener()方法,设置条目的点击事件,参数:OnItemClickListener对象 使用匿名内部类实现,重写onClick()方法,传递进来的参数:ListVie

  • Android利用startActivityForResult返回数据到前一个Activity

    在Android里面,从一个Activity跳转到另一个Activity.再返回,前一个Activity默认是能够保存数据和状态的.但这次我想通过利用startActivityForResult达到相同的目的,虽然看起来变复杂了,但可以探索下startActivityForResult背后的原理和使用注意事项. 要实现的功能如下: 从Activity A将数据传到Activity B,再从Activity B中获取数据后,再传回Activity A.在Activity B中添加一个"回到上一页&

随机推荐