美文网首页
android ViewModel&LiveData使用场景说明

android ViewModel&LiveData使用场景说明

作者: ZSGZ_AD | 来源:发表于2019-09-27 14:06 被阅读0次

    前言

    本篇文章主要讲解LiveData工作的原理,如果还不知道LiveData如何用的话,请参考官方文档
    LiveData的讲解涉及到了Lifecycle的知识,如果你还不了解LifeCycle,请参考文档LifeCycle介绍

    LiveData 是一个可以被观察的数据持有类,它可以感知 Activity、Fragment或Service 等组件的生命周期。简单来说,他主要有一下优点。

    它可以做到在组件处于激活状态的时候才会回调相应的方法,从而刷新相应的 UI。
    不用担心发生内存泄漏
    当 config 导致 activity 重新创建的时候,不需要手动取处理数据的储存和恢复。它已经帮我们封装好了。
    当 Actiivty 不是处于激活状态的时候,如果你想 livedata setValue 之后立即回调 obsever 的 onChange 方法,而不是等到 Activity 处于激活状态的时候才回调 obsever 的 onChange 方法,你可以使用 observeForever 方法,但是你必须在 onDestroy 的时候 removeObserver。
    回想一下,在你的项目中,是不是经常会碰到这样的问题,当网络请求结果回来的时候,你经常需要判断 Activity 或者 Fragment 是否已经 Destroy, 如果不是 destroy,才更新 UI。而当你如果使用 Livedata 的话,因为它是在 Activity 处于 onStart 或者 onResume 的状态时,他才会进行相应的回调,因而可以很好得处理这个问题,不必谢一大堆的 activity.isDestroyed()。接下来,让我们一起来看一下 LiveData 的使用.


    1569232134833.gif

    LiveData是抽象类不能直接创建对象,MutableLiveData是LiveData一个非常基本的继承类。
    例子中:是演示bind同一Activity 的多个Fragment间数据共享.我们在oneFragment中改变公共的viewmodel数据,在第twoFragment中绑定监听器.
    好了,上代码:
    viewModel代码:

    public class MainView2Model extends ViewModel {
        private int itemA,itemB = 0;
        public MutableLiveData<String> itemALive = new MutableLiveData();
        public MutableLiveData<SparseArray<String>> itemListLive= new MutableLiveData();
        public void changeItem(){
            itemALive.postValue("刷新数据");
            SparseArray<String> list = new SparseArray<>();
            for (int i = 0 ;i < 10; i++ ){
                list.put(i,new Random().nextInt(100)+"");
            }
            itemListLive.postValue(list);
        }
    }
    

    Activity代码:

    public class Main2Activity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener {
        MainView2Model mainViewModel;
        FrameLayout flContent;
        BottomNavigationBar bottomNavigationBar;
        private ArrayList<Fragment> fragments = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            flContent = findViewById(R.id.flContent);
            bottomNavigationBar = findViewById(R.id.bottom_navigation_bar);
            mainViewModel = ViewModelProviders.of(this).get(MainView2Model.class);
    
            bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED)
                    .setInActiveColor(R.color.color_ff333333)
                    .setActiveColor(R.color.colorPrimary)
                    .setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
            bottomNavigationBar.addItem(new BottomNavigationItem(R.mipmap.icon_practice, "首页"))
                    .addItem(new BottomNavigationItem(R.mipmap.icon_course, "啦啦").setActiveColorResource(R.color.color_ffd7b176))
                    .addItem(new BottomNavigationItem(R.mipmap.icon_my, "我的")).setFirstSelectedPosition(0).initialise();
            fragments = new ArrayList<>();
            fragments.add(new oneFragment());
            fragments.add(new TwoFragment());
            fragments.add(new ThreeFragment());
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction transaction = fm.beginTransaction();
            Fragment bookFragment = fragments.get(0);
            transaction.replace(R.id.flContent, bookFragment);
            transaction.commit();
            bottomNavigationBar.setTabSelectedListener(this);
        }
    
        @Override
        public void onTabSelected(int position) {
            if (fragments != null) {
                if (position < fragments.size()) {
                    FragmentManager fm = getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    Fragment fragment = fragments.get(position);
                    if (fragment.isAdded()) {
                        ft.replace(R.id.flContent, fragment);
                    } else {
                        ft.add(R.id.flContent, fragment);
                    }
                    ft.commitAllowingStateLoss();
                }
            }
        }
    
        @Override
        public void onTabUnselected(int position) {
            if (fragments != null) {
                if (position < fragments.size()) {
                    FragmentManager fm = getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    Fragment fragment = fragments.get(position);
                    ft.remove(fragment);
                    ft.commitAllowingStateLoss();
                }
            }
        }
    
        @Override
        public void onTabReselected(int position) {
    
        }
    }
    
    

    Fragment代码:

    public class oneFragment extends Fragment {
        private View view;
        MainView2Model mainView2Model;
        private TextView oneTv;
        private TextView oneTv1;
        private Button oneBt;
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.fragment_one, container, false);
            oneTv = view.findViewById(R.id.oneTv);
            oneTv1 = view.findViewById(R.id.oneTv1);
            oneBt = view.findViewById(R.id.oneBt);
    
            mainView2Model = ViewModelProviders.of(this.getActivity()).get(MainView2Model.class);
            mainView2Model.itemALive.observe(this, new Observer<String>() {
                @Override
                public void onChanged(@Nullable String string) {
                   // oneTv.setText(string);
                }
            });
    
            oneBt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) { //给被观察者MutableLiveData的对象设置值,值改变了,就会回调上面的观察监听器
                    mainView2Model.changeItem();
                   // Toast.makeText(oneFragment.this.getActivity(),"ssss",Toast.LENGTH_SHORT).show();
                }
            });
    
            mainView2Model.itemListLive.observe(this, new Observer<SparseArray<String>>() {
                @Override
                public void onChanged(@Nullable SparseArray<String> stringSparseArray) {
                    StringBuffer sb = new StringBuffer();
                    for (int i = 0;i<stringSparseArray.size();i++){
                        sb.append(stringSparseArray.get(i)+";");
                    }
                    oneTv1.setText(sb.toString());
                }
            });
            return view;
        }
    }
    
    package com.example.acandroidlisten.objectanimator.viewmodelDemo.fragment;
    
    import android.arch.lifecycle.MutableLiveData;
    import android.arch.lifecycle.Observer;
    import android.arch.lifecycle.ViewModelProviders;
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.SparseArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import com.example.acandroidlisten.objectanimator.R;
    import com.example.acandroidlisten.objectanimator.viewmodelDemo.MainView2Model;
    
    import java.util.List;
    
    public class TwoFragment extends Fragment {
        private View view;
        private MainView2Model mainView2Model;
        TextView twoTv;
        RecyclerView twoRecyclerView;
        MyRecyclerViewAdapter myRecyclerViewAdapter = null;
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.fragment_two, container, false);
            mainView2Model = ViewModelProviders.of(this.getActivity()).get(MainView2Model.class);
            twoTv = view.findViewById(R.id.twoTv);
            twoRecyclerView = view.findViewById(R.id.twoRecyclerView);
            twoRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
            myRecyclerViewAdapter =  new MyRecyclerViewAdapter(twoRecyclerView,mainView2Model.itemListLive.getValue());
            twoRecyclerView.setAdapter(myRecyclerViewAdapter);
    
            mainView2Model.itemALive.observe(this, new Observer<String>() {
                @Override
                public void onChanged(@Nullable String string) { //创建一个观察监听器
                    twoTv.setText(string);
                }
            });
            mainView2Model.itemListLive.observe(this, new Observer<SparseArray<String>>() {
                @Override
                public void onChanged(@Nullable SparseArray<String> stringSparseArray) { //创建一个观察监听器
                    myRecyclerViewAdapter.notifyDataSetChanged();
                }
            });
            return view;
        }
    
        class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.RecyclerHolder> {
            private Context mContext;
            private SparseArray<String> dataList = new SparseArray<>();
    
            public MyRecyclerViewAdapter(RecyclerView recyclerView,SparseArray<String> dataList) {
                this.mContext = recyclerView.getContext();
                if (null != dataList) {
                    this.dataList = dataList;
                }
            }
    
            public void setData(SparseArray<String> dataList) {
                if (null != dataList) {
                    this.dataList = dataList;
                    notifyDataSetChanged();
                }
            }
    
            @Override
            public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_fragment_two, parent, false);
                return new RecyclerHolder(view);
            }
    
            @Override
            public void onBindViewHolder(RecyclerHolder holder, int position) {
                holder.textView.setText(dataList.get(position));
            }
    
            @Override
            public int getItemCount() {
                return dataList.size();
            }
    
            class RecyclerHolder extends RecyclerView.ViewHolder {
                TextView textView;
    
                private RecyclerHolder(View itemView) {
                    super(itemView);
                    textView = (TextView) itemView.findViewById(R.id.text_adapter1);
                }
            }
        }
    }
    

    Xml相关文件:

    //activity
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <FrameLayout
            android:id="@+id/flContent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    
        <com.ashokvarma.bottomnavigation.BottomNavigationBar
            android:id="@+id/bottom_navigation_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:elevation="2dp"
            android:translationZ="2dp" />
    
    </LinearLayout>
    
    
    //fragment
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/oneTv"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:text="第一页"
            android:textColor="#ffffff" />
    
        <TextView
            android:id="@+id/oneTv1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/oneTv"
            android:background="#ffeedd"
            android:gravity="center"
            android:padding="16dp"
            android:text="数据"
            android:textColor="@color/colorPrimary" />
    
        <Button
            android:id="@+id/oneBt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:textSize="16dp"
            android:padding="6dp"
            android:layout_marginBottom="16dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:textColor="#ffffff"
            android:text="共享数据" />
    
    </RelativeLayout>
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/twoTv"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:text="第二页"
            android:textColor="#ffffff"
            android:gravity="center"
            android:background="@color/colorPrimary"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/twoRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
    </LinearLayout>
    
    

    源码地址:https://github.com/sgl890226/objectanimator

    相关文章

      网友评论

          本文标题:android ViewModel&LiveData使用场景说明

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