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

项目地址

一.项目简介

本项目完成了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 源码

猜你喜欢

转载自blog.csdn.net/z979451341/article/details/81185356