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

Android六大官方构架组件的基础使用(Lifecycle,LiveData,ViewModel,Room,Paging,Navigation)

程序员文章站 2024-03-17 13:56:28
...

项目地址

一.项目简介

本项目完成了Lifecycle,LiveData,ViewModel,Room,Paging,Navigation这六个官方构架组件的基础使用,主要会为了初步了解这些组件的基础使用,所以对于这些组件的高级用法和深度思考是缺乏的。但是大家可以通过本项目初步了解这些组件的基础作用和用法。

贴一张项目主界面图,大家可以先下载项目自己运行一下

Android六大官方构架组件的基础使用(Lifecycle,LiveData,ViewModel,Room,Paging,Navigation)

 

二.对于六大组件的简介

1.Lifecycle(监听activity生命周期)

Lifecycle主要作用是监听activity生命周期,比如方便大家使用MVP的时候Presenter监听activity生命周期。还可以与Rxjava配合,所以有了RxLifecycle框架。

getLifecycle().addObserver(new IPresenter());


    class IPresenter implements LifecycleObserver {


        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        void onCreate( LifecycleOwner owner){
            tv.setText(tv.getText()+"onCreate\n");
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        void onStart( LifecycleOwner owner){
            tv.setText(tv.getText()+"onStart\n");
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        void onResume( LifecycleOwner owner){
            tv.setText(tv.getText()+"onResume\n");
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        void onDestroy( LifecycleOwner owner){
            tv.setText(tv.getText()+"onDestroy\n");
        }

    }

 

2.LiveData(监听自身变化的数据类)

LIveData,比如:MutableLiveData<Integer>。这个数据类有着监听自身变化的能力,并且通过监听者模式告诉 其他组件数据更新。这个能够与ViewModel、Room配合,这个后面说

    MutableLiveData<Integer> num=new MutableLiveData<>();
    MyObserver observer;        

        observer=new MyObserver();
        num.observe(this,observer);

    class MyObserver implements Observer<Integer> {

        @Override
        public void onChanged(@Nullable Integer integer) {
            tv.setText(""+integer);
        }
    }

 

3.ViewModel(跨组件通讯)

我们先看看我们如何获取ViewModel这个类的对象
ViewModelProviders.of(getActivity()).get(MyViewModel.class);

而这个getActivity()也可以换成Fragment的实例

现在我说一下这个为何能够做到跨组件通讯,因为它能跨组件获取同一个实例

比如:在ActivityA里有FragmentA、FragmentB,你在FragmentA通过给getActivity()得到ViewModel的实例,和你在FragmentB也这样做得到的实例是一样的。说白了,在FragmentA你如果改变这个ViewModel的LIveData这样的属性,在FragmentB能够监听的到

        viewModel= ViewModelProviders.of(getActivity()).get(MyViewModel.class);
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewModel.setNum(viewModel.getNum().getValue()+1);
            }
        });
        viewModel= ViewModelProviders.of(getActivity()).get(MyViewModel.class);
        viewModel.getNum().observe(this,new MyObserver());

 

4.Room(数据库框架)

Room有三个部分:实体类、数据库操控类、数据库创建类

实体类,和GreenDao、Realm一样通过注解来创建表,和修改属性

这个是实体类的属性能够是LIveData

@Entity(tableName = "test")
public class TestBean {

    @PrimaryKey
    private long id;

    private String name="";

......
}

数据库操控类,你别看他是接口类,但是他通过Room框架的注解却有着真正的操控数据的能力,

@Dao
public interface TestDao {

    @Query("SELECT * FROM test")
    List<TestBean> getAll();

    @Query("SELECT * FROM test WHERE id = (:id)")
    TestBean getById(int id);

    @Insert
    void insert(TestBean testBean);

    @Delete
    void delete(TestBean testBean);

    @Update
    void update(TestBean testBean);

}

数据库创建类,能够创建数据库,并且能够修改数据库版本

@Database(entities = {TestBean.class},version = 1)
public abstract class TestDataBase extends RoomDatabase{

    public abstract TestDao testDao();


}

这个Room能够与RxJava合作,具体的看官网

 

5.Paging(分页加载)

Paging实现的分页加载指的是:你如果有100条数据,但是你的屏幕能够显示出来的只有10条,那你把100条item都加载到RecyclerView里,就会浪费内存,那你先给RecyclerView加载20条数据,当你把RecyclerView拉到底部,Paging再给RecyclerView 20条数据,让他再加载出20条item给用户看。

还是三个步骤实现Paging的基础使用

第一个LiveData数据类,这个PageSize就是你每一次给RecyclerView的数据数量

val allCheeses = LivePagedListBuilder(dao.allCheesesByName(), PagedList.Config.Builder()
                    .setPageSize(PAGE_SIZE)
                    .setEnablePlaceholders(ENABLE_PLACEHOLDERS)
                    .build()).build()

第二个实现PagedListAdapter,其中还用了DiffUtil这个帮助RecyclerView优化更新的工具类

class CheeseAdapter : PagedListAdapter<Cheese, CheeseViewHolder>(diffCallback) {
    override fun onBindViewHolder(holder: CheeseViewHolder, position: Int) {
        holder.bindTo(getItem(position))
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CheeseViewHolder =
            CheeseViewHolder(parent)

    companion object {

        private val diffCallback = object : DiffUtil.ItemCallback<Cheese>() {
            override fun areItemsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
                    oldItem.id == newItem.id

            override fun areContentsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
                    oldItem == newItem
        }
    }
}

第三个将Adapter与数据库连接起来

viewModel.allCheeses.observe(this, Observer(adapter::submitList))

说实话代码太多了,大家还是看看项目代码比较好,这个例子是Kotlin的语言,我是从官方例子里弄出来的

 

6.Navigation(Fragment控制框架)

通过使用xml文件来设置Fragment的跳转逻辑和跳转动画

每一个fragment标签里都设置了id和对应Fragment路径、还有layout。并且还定义了action这个标签,设置了destination目的地,和四个跳转动画

<?xml version="1.0" encoding="utf-8"?>
<navigation 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"
    app:startDestination="@id/page1Fragment">

    <fragment
        android:id="@+id/page1Fragment"
        android:name="com.example.lilingzhi.llvr.fragment.MainPage1Fragment"
        android:label="fragment_page1"
        tools:layout="@layout/fragment_main_page1">
        <action
            android:id="@+id/action_page2"
            app:destination="@id/page2Fragment"
            app:enterAnim="@anim/slide_right_in"
            app:exitAnim="@anim/slide_left_out"
            app:popEnterAnim="@anim/slide_left_in"
            app:popExitAnim="@anim/slide_right_out" />
    </fragment>

    <fragment
        android:id="@+id/page2Fragment"
        android:name="com.example.lilingzhi.llvr.fragment.MainPage2Fragment"
        android:label="fragment_page2"
        tools:layout="@layout/fragment_main_page2">
        <action
            android:id="@+id/action_page1"
            app:enterAnim="@anim/slide_right_in"
            app:exitAnim="@anim/slide_left_out"
            app:popEnterAnim="@anim/slide_left_in"
            app:popExitAnim="@anim/slide_right_out"
            app:popUpTo="@id/page1Fragment" />
        <action
            android:id="@+id/action_page3"
            app:destination="@id/nav_graph_page3"
            app:enterAnim="@anim/slide_right_in"
            app:exitAnim="@anim/slide_left_out"
            app:popEnterAnim="@anim/slide_left_in"
            app:popExitAnim="@anim/slide_right_out" />
    </fragment>

    <navigation
        android:id="@+id/nav_graph_page3"
        app:startDestination="@id/page3Fragment">
        <fragment
            android:id="@+id/page3Fragment"
            android:name="com.example.lilingzhi.llvr.fragment.MainPage3Fragment"
            android:label="fragment_page3"
            tools:layout="@layout/fragment_main_page3" />
    </navigation>

</navigation>

java类里触发action

        btn.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.action_page2)
        }

 

三.自我评论

因为我自身对这些组件的了解和掌握不够,所以没有写成 真正算的是 符合官方推荐 构架项目。

关于这个博客算是未完待续

 

参考文章

Android架构组件(二)——LiveData

Android架构组件Room的使用

Android官方架构组件Navigation:大巧不工的Fragment管理框架

Android.Arch.Paging: 分页加载的新选项

Android 架构组件(一)——Lifecycle-Aware Components

Android架构组件(三)——ViewModel

官网

官方github 源码