欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android--Jetpack的使用(一)

程序员文章站 2022-03-11 16:25:01
目录1、ViewModel2、ViewModel + LiveData3、ViewModel + LiveData + dataBinding4、ViewModel + SavedStateHandle + LiveData + dataBinding5、例子下载  参考文献1、ViewModel  ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存例子:代码:MyVModelimport and...

目录

1、ViewModel

2、ViewModel + LiveData

3、ViewModel + LiveData + dataBinding

4、ViewModel + SavedStateHandle + LiveData + dataBinding

5、例子下载

  参考文献


1、ViewModel

  ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存

例子:

Android--Jetpack的使用(一)

代码:

MyVModel

import androidx.lifecycle.ViewModel;

public class MyVModel extends ViewModel {
    public int num=0;
}

MainActivity

//创建MyVModel
myVModel = AndroidViewModelFactory.getInstance(getApplication()).create(MyVModel.class);
//+1
myVModel.num++;
tv.setText(String.valueOf(myVModel.num));
//+2
myVModel.num += 2;
tv.setText(String.valueOf(myVModel.num));

2、ViewModel + LiveData

  LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

例子:

Android--Jetpack的使用(一)

代码:

MyVModelWithLiveData

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MyVModelWithLiveData extends ViewModel {
    //创建LiveData对象
    private MutableLiveData<Integer> data;
    //创建get方法
    public MutableLiveData<Integer> getNum() {
        //当第一次get的时候初始化
        if (null == data) {
            data = new MutableLiveData<>();
            data.setValue(0);
        }
        return data;
    }
    //方法
    public void addNum(int a) {
        data.setValue(data.getValue() + a);

    }
}

MainActivity

//创建viewmodel
myVModelWithLiveData = AndroidViewModelFactory.getInstance(getApplication()).create(MyVModelWithLiveData.class);
//观察LiveData对象
myVModelWithLiveData.getNum().observe(this, new Observer<Integer>() {
    @Override
    public void onChanged(Integer integer) {
        //当监听到数据发生变化时跟新界面
        tv1.setText(String.valueOf(integer ));
    }
});

3、ViewModel+LiveData+dataBinding

  在原来的方法中,就是通过findviewById()的方法拿到TextView,然后通过setText方法把viewmodel中的numberTextView绑定到一块.

  在使用了dataBinding以后,就可以使用赋值表达式@{}来实现绑定,如下:

  <TextView
            android:text="@{String.valueOf(vmodel.number),default=0}" />
例子

Android--Jetpack的使用(一)

代码

module的build.gradle

android {
   ...
   /*配置使用dataBinding*/
    buildFeatures {
        dataBinding true;
    }
    /*配置使用jdk1.8,因为会用到Lambda表达式*/
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

MyViewModel

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MyViewModel extends ViewModel {
    private MutableLiveData<Integer> number;
    //控制显隐
    private MutableLiveData<Boolean> isVisibiliy;

    public MutableLiveData<Integer> getNumber() {
        if (null == number) {
            number = new MutableLiveData<>();
            number.setValue(0);
        }
        return number;
    }

    public MutableLiveData<Boolean> getIsVisibiliy() {
        if (isVisibiliy == null) {
            isVisibiliy = new MutableLiveData<>();
            isVisibiliy.setValue(true);
        }
        return isVisibiliy;
    }

    public void setIsVisibiliy() {
        isVisibiliy.setValue(!isVisibiliy.getValue());
    }

    public void addNum(int num) {
        number.setValue(number.getValue() + num);
    }

}

布局文件

<?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>
        <!--导入View类-->
        <import type="android.view.View" />
        <variable
            name="vmodel"
            type="com.example.d0810.MyViewModel" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        tools:context=".MainActivity2">

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{String.valueOf(vmodel.number),default=0}"
            android:textSize="30sp" />

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->vmodel.addNum(1)}"
            android:text="+1" />

        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->vmodel.addNum(2)}"
            android:text="+2" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:background="#000" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_v"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="文本"
                android:textSize="28sp"
                android:visibility="@{vmodel.isVisibiliy ? View.VISIBLE : View.INVISIBLE}" />

            <Button
                android:id="@+id/btn_v"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="@{() -> vmodel.setIsVisibiliy()}"
                android:text="控制显隐" />
        </LinearLayout>

    </LinearLayout>
</layout>

MainActivity2

public class MainActivity2 extends AppCompatActivity {
    private ActivityMain2Binding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyViewModel myViewModel = AndroidViewModelFactory.getInstance(getApplication()).create(MyViewModel.class);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main2);
        binding.setVmodel(myViewModel);
        //
        binding.setLifecycleOwner(this);
    }
}

4、ViewModel的SavedStateHandle

  当程序推出到后台的时候,然后被手机系统回收导致的进程终止,在原来的方式是使用 onSaveInstanceState()方法来进行保存数据和状态。

  所以在 ViewModel的构造函数的时候会接收一个 SavedStateHandle 对象,这是一个键值对映射,用户保存状态。

注意: 状态必须是简单的轻量级状态。对于复杂或大型数据,您应该使用本地持久性存储。

SavedStateHandle所有的方法
  • get(String key) :根据键值来获取数组
  • contains(String key):判断handle中是否包含key这个键
  • remove(String key):根据键值删除数据
  • set(String key, T value):保存数据
  • keys():获取所有的键值
  • getLiveData(String key):返回封装在LiveData可观察对象中的值。
例子效果图

Android--Jetpack的使用(一)Android--Jetpack的使用(一)Android--Jetpack的使用(一)

SavedStateHandle的使用

 ScoreVmodel

public class ScoreVmodel extends ViewModel {
    public final String ASCORE = "aScore";
    public final String BSCORE = "bScore";
    public final String AUNDOSCORE = "aUndoScore";
    public final String BUNDOSCORE = "bUndoScore";
//保存状态模块
private SavedStateHandle handle;
public ScoreVmodel(SavedStateHandle handle) {
    this.handle = handle;
}

    //获取A队的分数
    public MutableLiveData<Integer> getaScore() {
        if (!handle.contains(ASCORE)) {
            handle.set(ASCORE, 0);
        }
        return handle.getLiveData(ASCORE);
    }

    //获取B队的分数
    public MutableLiveData<Integer> getbScore() {
        if (!handle.contains(BSCORE)) {
            handle.set(BSCORE, 0);
        }
        return handle.getLiveData(BSCORE);
    }

    //添加A队的分数
    public void addAScore(int s) {
        //首先把A队和B队的分数保存起来
        handle.set(AUNDOSCORE, getaScore().getValue());
        handle.set(BUNDOSCORE, getbScore().getValue());
        getaScore().setValue(getaScore().getValue() + s);
    }

    //添加B队的分数
    public void addBScore(int s) {
        //首先把A队和B队的分数保存起来
        handle.set(AUNDOSCORE, getaScore().getValue());
        handle.set(BUNDOSCORE, getbScore().getValue());
        //再计算分数
        getbScore().setValue(getbScore().getValue() + s);
    }

    public void reset() {
        //首先把A队和B队的分数保存起来
        handle.set(AUNDOSCORE, getaScore().getValue());
        handle.set(BUNDOSCORE, getbScore().getValue());
        handle.set(ASCORE, 0);
        handle.set(BSCORE, 0);
    }

    //撤回一次
    public void undoScore() {
        handle.set(ASCORE, handle.getLiveData(AUNDOSCORE).getValue());
        handle.set(BSCORE, handle.getLiveData(BUNDOSCORE).getValue());
    }
}

 ScoreActivity

public class ScoreActivity extends AppCompatActivity {
    private ActivityScoreBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_score);
        ScoreVmodel vmodel = new ViewModelProvider(this, new SavedStateViewModelFactory(getApplication(), this)).get(ScoreVmodel.class);
        binding.setModel(vmodel);
        /**
         * 这句话时必须要加上的,这个方法的注释如下
         *   Sets the {@link LifecycleOwner} that should be used for observing changes of
         *   LiveData in this binding. If a {@link LiveData} is in one of the binding expressions
         *   and no LifecycleOwner is set, the LiveData will not be observed and updates to it
         *   will not be propagated to the UI.
         * 我理解的大概意思就是 这个方法就是把 LifecycleOwner 和 LiveData 绑定到一块,只有绑定到一块。当
         * 数据发生变化的时候 才会更新UI界面
         */
        binding.setLifecycleOwner(this);
    }
}

 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="model"
            type="com.example.d0810.score.ScoreVmodel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".score.ScoreActivity">

        <TextView
            android:id="@+id/tv_ta"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/a"
            android:textColor="@color/teamAColor"
            android:textSize="@dimen/teamSizeText"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline2" />

        <TextView
            android:id="@+id/tv_tb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/b"
            android:textColor="@color/teamBColor"
            android:textSize="@dimen/teamSizeText"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline2" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.05" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.2" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.35" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.5" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.65" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.75" />

        <TextView
            android:id="@+id/tv_ascore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(model.getaScore()),default=@string/zero}"
            android:textColor="@color/teamAColor"
            android:textSize="@dimen/scoreTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline3" />

        <TextView
            android:id="@+id/tv_bscore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(model.getbScore()),default=@string/zero}"
            android:textColor="@color/teamBColor"
            android:textSize="@dimen/scoreTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.504"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline3" />

        <Button
            android:id="@+id/btn_a1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamAColor"
            android:onClick="@{() -> model.addAScore(1) }"
            android:text="@string/add1"
            android:textColor="@android:color/white"
            android:textSize="30sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline4"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline4" />

        <Button
            android:id="@+id/btn_a2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamAColor"
            android:onClick="@{() -> model.addAScore(2) }"
            android:text="@string/add2"
            android:textColor="@android:color/white"
            android:textSize="@dimen/btnTextsize"
            app:layout_constraintBottom_toTopOf="@+id/guideline5"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline5" />

        <Button
            android:id="@+id/btn_a3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamAColor"
            android:onClick="@{() -> model.addAScore(3) }"
            android:text="@string/add3"
            android:textColor="@android:color/white"
            android:textSize="@dimen/btnTextsize"
            app:layout_constraintBottom_toTopOf="@+id/guideline6"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline6" />

        <Button
            android:id="@+id/btn_b3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamBColor"
            android:onClick="@{() -> model.addBScore(3) }"
            android:text="@string/add3"
            android:textColor="@android:color/white"
            android:textSize="@dimen/btnTextsize"
            app:layout_constraintBottom_toTopOf="@+id/guideline6"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline6" />

        <Button
            android:id="@+id/btn_b2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamBColor"
            android:onClick="@{() -> model.addBScore(2)}"
            android:text="@string/add2"
            android:textColor="@android:color/white"
            android:textSize="@dimen/btnTextsize"
            app:layout_constraintBottom_toTopOf="@+id/guideline5"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline5" />

        <Button
            android:id="@+id/btn_b1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/teamBColor"
            android:onClick="@{() -> model.addBScore(1) }"
            android:text="@string/add1"
            android:textColor="@android:color/white"
            android:textSize="@dimen/btnTextsize"
            app:layout_constraintBottom_toTopOf="@+id/guideline4"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline4" />

        <ImageButton
            android:id="@+id/ibtn_undo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/undo"
            android:onClick="@{() -> model.undoScore() }"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline7"
            app:srcCompat="@drawable/ic_baseline_undo_24" />

        <ImageButton
            android:id="@+id/ibtn_reset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/reset"
            android:onClick="@{() -> model.reset()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toTopOf="@+id/guideline7"
            app:srcCompat="@drawable/ic_baseline_loop_24" />

        <View
            android:id="@+id/textView"
            android:layout_width="0dp"
            android:layout_height="2dp"
            android:layout_marginBottom="5dp"
            android:background="@android:color/darker_gray"
            app:layout_constraintBottom_toTopOf="@+id/guideline7"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

5、例子下载

https://download.csdn.net/download/ljp345775/12702818

参考文献

[1] Android开发教程(2019最新版,使用JetPack)
[2] Android官方的开发文档

本文地址:https://blog.csdn.net/ljp345775/article/details/107925929

相关标签: # Jetpack