美文网首页Android应用开发那些事
Android (2019) 新工具类Jetpack学习 ---

Android (2019) 新工具类Jetpack学习 ---

作者: 良人_Coder | 来源:发表于2019-10-12 10:58 被阅读0次

    env : android studio 3.5, Android Q
    data : 2019/10/12
    author : lrcoder


    使用Jetpack开发工具的优势

    • 代码结构逻辑更加模块化
    • 代码向后兼容, 减少系统崩溃和内存泄漏的问题
    • 方便代码管理,Jetpack可以管理(后台任务、导航栏、生命周期等)
    • 提高代码运行效率

    1.ViewModel

    ViewModel 可以用作储存界面数据,取代Bundle savedInstanceState存储数据。ViewModel就是一个存储着我们界面数据的类,界面数据的设定全部来自自定义的ViewModel。

    首先,我们需要对某一个界面(例如:MainActivity)设定一个ViewModel(Demo中使用的是MyViewModel 继承自 ViewModel)

    • 我需要对每一个界面定义一个专属的ViewModel,这样易于维护,且代码较为美观;
    • ViewModel的包为androidx.lifecycle.ViewModel
    • MainActivity 需要引用包androidx.lifecycle.ViewModelProviders,注意ViewModelProviders后需要有"s",使用时需要添加依赖implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    import androidx.lifecycle.ViewModel;
    
    class MyViewModel extends ViewModel {
    
        private int textViewContent = 0;
    
        int getTextViewContent() {
            return textViewContent;
        }
    
        void setTextViewContent(int textViewContent) {
            this.textViewContent = textViewContent;
        }
    }
    

    接着我们在MainActivity中声明和使用我们针对于该Activity创建的ViewModel

    //获取ViewModel类的对象
    MyViewModel myViewModel;
    
    //在onCreate()方法中获取ViewModel的具体内容
    myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    

    也就是说以后我们在给控件赋值时只需要获取ViewModel实例中的数值即可,修改数值也是直接修改ViewModel中对应的数值

    //修改数值为当前 textViewContent + 1
    myViewModel.setTextViewContent(myViewModel.getTextViewContent() + 1);
    
    //给控件赋值为 textViewContent + 1
    textView.setText(String.valueOf(myViewModel.getTextViewContent()));
    
    //为了保证每次界面销毁重启后,都可以保存之前的值,我们需要在onCreate()中,给控件赋值为 textViewContent
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
            textView = findViewById(R.id.text);
            textView.setText(String.valueOf(myViewModel.getTextViewContent()));
        }
    

    2、LiveData

    LiveData的作用是让底层数据更新时,自动更新界面控件视图,减少手动setText()

    同样作为视图数据管理的一个类,LiveData写在ViewModel类中。将被管理的值放于MutableLiveData<>容器中

    • 注意MyViewModel类MyViewModel类的声明需要是public
    • 注意拓展MutableLiveData<>容器中可以存放多种数据类型List<>String等等
    • 需要提供修改参数的方法
    public class MyViewModel extends ViewModel {
    
        private MutableLiveData<Integer> textViewContent;
        public MyViewModel(){
            textViewContent = new MutableLiveData<>();
            textViewContent.setValue(0);
        }
    
        MutableLiveData<Integer> getTextViewContent() {
            if (textViewContent == null) {
                textViewContent = new MutableLiveData<>();
                textViewContent.setValue(0);
            }
            return textViewContent;
        }
    
        void addTextViewContent(int n) {
            textViewContent.setValue(textViewContent.getValue() + n);
        }
    }
    
    

    接着在MainActivity中声明控件、声明ViewModel管理类、绑定ViewModel管理类、设置LiveData观察者

    • 点击事件由直接设置控件值变为设置ViewModel对应属性值
    • 控件属性值通过观察者的onChanged()方法设置
    • 代码和视图分离,代码结构更加清晰
    
    public class MainActivity extends AppCompatActivity {
    
        //声明控件
        MyViewModel myViewModel;
        Button button1, button2;
        TextView textView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //绑定视图
            setContentView(R.layout.activity_main);
    
            //找到控件
            textView = findViewById(R.id.text1);
            button1 = findViewById(R.id.button2);
            button2 = findViewById(R.id.button);
    
            //绑定ViewModel管理类
            myViewModel = ViewModelProviders.of(this).get(MyViewModelTest.class);
    
            //设置ViewModel观察者
            myViewModel.getTextViewContent().observe(this, new Observer<Integer>() {
                @Override
                public void onChanged(Integer integer) {
                    textView.setText(String.valueOf(integer));
                }
            });
    
            button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    myViewModel.addTextViewContent(1);
                }
            });
    
            button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    myViewModel.addTextViewContent(2);
                }
            });
        }
    }
    

    3、Data Binding

    将数据和View绑定,减少声明控件、减少找到控件的过程

    data Binding的使用和声明涉及到build.gradleJavaxml三个部分。

    首先在build.gradle中打开dataBinding的开关

        dataBinding{
            enabled=true
        }
    

    接下来完成Java部分的ViewModel的创建

    public class MyViewModel extends ViewModel {
    
        private MutableLiveData<Integer> textViewContent;
    
        public MyViewModel(){
            textViewContent = new MutableLiveData<>();
            textViewContent.setValue(0);
        }
    
        public MutableLiveData<Integer> getTextViewContent() {
            if (textViewContent == null) {
                textViewContent = new MutableLiveData<>();
                textViewContent.setValue(0);
            }
            return textViewContent;
        }
    
        public void addTextViewContent(int n) {
            textViewContent.setValue(textViewContent.getValue() + n);
        }
    }
    
    

    MainActivity中进行控件的绑定、声明

    由于在build.gradle中打开了dataBinding的开关,那么我们可以在MainActivity中获取一个类ActivityMainBinding,这个是动态生成的,名称的组合为res-layout-activity_main.xml.xml文件的名字加上Binding

    • binding.setMyViewModel(myViewModel)中的MyViewModel,需要和xml文件中的name属性相对应
    public class MainActivity extends AppCompatActivity {
    
        MyViewModel myViewModel;
        //声明绑定的xml文件
        ActivityMainBinding binding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //绑定xml视图文件
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            //绑定ViewModel管理类
            myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
            //声明属性(该属性与xml文件中设置的数据name相对应)
            binding.setMyViewModel(myViewModel);
            //声明视图生命周期拥有者
            binding.setLifecycleOwner(this);
        }
    }
    

    最后修改xml文件内容

    • 使用layout标签包裹整个xml文件
    • 添加data标签
    • data标签中添加variable标签来规定使用的数据名、绑定的ViewModel
    • xml文件中设置text的属性内容
      • 变量的使用格式为@{name.变量名(可能需要在其中做一些类型转换)}
      • 函数的使用格式为@{()->name.函数(包括参数)}
    <?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="myViewModel"
                type="com.code.databingdingdemo.MyViewModel" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
    
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
    
            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(myViewModel.textViewContent)}"
                android:textSize="40sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_bias="0.479"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.341" />
    
            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="356dp"
                android:onClick="@{()->myViewModel.addTextViewContent(1)}"
                android:text="+1"
                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.116" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    

    相关文章

      网友评论

        本文标题:Android (2019) 新工具类Jetpack学习 ---

        本文链接:https://www.haomeiwen.com/subject/zefqmctx.html