Jetpack学习(三)——LiveData&ViewModel

jetpack学习(三)——LiveData&ViewModel

LiveData

使用 LiveData 的优势

确保界面符合数据状态
LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。
不会发生内存泄露
观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
共享资源
您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。

使用 LiveData 对象

  • 1.创建 LiveData 实例以存储某种类型的数据。这通常在 ViewModel 类中完成。
  • 2.创建可定义 onChanged() 方法的 Observer 对象,该方法可以控制当 LiveData 对象存储的数据更改时会发生什么。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中创建 Observer 对象。
  • 3.使用 observe() 方法将 Observer 对象附加到 LiveData 对象。observe() 方法会采用 LifecycleOwner 对象。这样会使 Observer 对象订阅 LiveData 对象,以使其收到有关更改的通知。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中附加 Observer 对象。

创建LiveData对象<相关依赖略>

    public class NameViewModel extends ViewModel {
        // Create a LiveData with a String
    private MutableLiveData<String> currentName;

        public MutableLiveData<String> getCurrentName() {
            if (currentName == null) {
                currentName = new MutableLiveData<String>();
            }
            return currentName;
        }

    // Rest of the ViewModel...
    }
    

观察 LiveData 对象

public class NameActivity extends AppCompatActivity {

        private NameViewModel model;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Other code to setup the activity...

            // Get the ViewModel.
            model = ViewModelProviders.of(this).get(NameViewModel.class);

            // Create the observer which updates the UI.
            final Observer<String> nameObserver = new Observer<String>() {
                @Override
                public void onChanged(@Nullable final String newName) {
                    // Update the UI, in this case, a TextView.
                    nameTextView.setText(newName);
                }
            };

            // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
            model.getCurrentName().observe(this, nameObserver);
        }
    }

如下为AS自动创建带有ViewModel的Fragment,注意ViewModel直接在onActivityCreated初始化

public class BlankFragment extends Fragment {

    private BlankViewModel mViewModel;

    public static BlankFragment newInstance() {
        return new BlankFragment();
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.blank_fragment, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mViewModel = ViewModelProviders.of(this).get(BlankViewModel.class);
        // TODO: Use the ViewModel
    }

}

更新LiveData

 button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String anotherName = "John Doe";
            model.getCurrentName().setValue(anotherName);
        }
    });

ViewModel<相关依赖略>

实现 ViewModel

创建MyViewModel

 public class MyViewModel extends ViewModel {
        private MutableLiveData<List<User>> users;
        public LiveData<List<User>> getUsers() {
            if (users == null) {
                users = new MutableLiveData<List<User>>();
                loadUsers();
            }
            return users;
        }

        private void loadUsers() {
            // Do an asynchronous operation to fetch users.
        }
    }

访问

 public class MyActivity extends AppCompatActivity {
        public void onCreate(Bundle savedInstanceState) {
            // Create a ViewModel the first time the system calls an activity's onCreate() method.
            // Re-created activities receive the same MyViewModel instance created by the first activity.

            MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
            model.getUsers().observe(this, users -> {
                // update UI
            });
        }
    }
    

databinding+viewmodel+livedata结合使用

activity_view_model.xml

直接可以再布局文件中引用相关的viewmodel

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
    <import type="android.view.View.OnClickListener"/>
        <import type="com.hwp.databindingdemo.NameViewModel"/>
        <variable
            name="mode"
            type="NameViewModel" />
        <variable
            name="myClickListener"
            type="OnClickListener" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.ViewModelActivity">
        <TextView
            android:text="@{mode.name}"
            tools:text="name"
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="@{mode.nameList[0]}"
            tools:text="nameList"
            android:id="@+id/tv_name_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:onClick="@{myClickListener}"
            android:id="@+id/btn_01"
            android:text="按钮一"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:onClick="@{myClickListener}"
            android:id="@+id/btn_02"
            android:text="按钮二"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</layout>

ViewModelActivity.java

public class ViewModelActivity extends AppCompatActivity implements View.OnClickListener {

    private NameViewModel nameViewModel;
    private  ActivityViewModelBinding viewModelBinding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModelBinding= DataBindingUtil.setContentView(this,R.layout.activity_view_model);
        viewModelBinding.setMyClickListener(this);
        nameViewModel=ViewModelProviders.of(this).get(NameViewModel.class);
        //databing设置viewmodel
        viewModelBinding.setMode(nameViewModel);
        viewModelBinding.setLifecycleOwner(this);
        //使用databing后,如下方法都可以省略了,更加便捷了
       /* nameViewModel.getName().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String str) {

            }
        });
        nameViewModel.getNameList().observe(this, new Observer<List<String>>() {
            @Override
            public void onChanged(List<String> strings) {

            }
        });*/
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_01:
                nameViewModel.getName().setValue("我是值");
               // viewModelBinding.setMode(nameViewModel);
                break;
            case R.id.btn_02:
                List<String> list=new ArrayList<>();
                list.add("值一");
                list.add("值二");
                list.add("值三");
                nameViewModel.getNameList().setValue(list);
               // viewModelBinding.setMode(nameViewModel);
                break;
        }
    }
}

NameViewModel.java

public class NameViewModel extends ViewModel {
    private MutableLiveData<String> mName;
    private  MutableLiveData<List<String>> mNameList;
    public MutableLiveData<String> getName(){
        if(mName==null){
            mName=new MutableLiveData<>();
        }
        return mName;
    }
    public MutableLiveData<List<String>> getNameList(){
        if(mNameList==null){
            mNameList=new MutableLiveData<>();
        }
        return mNameList;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • [TOC] LiveData LiveData概述 LiveData是一个可观察的数据持有者类。与常规observ...
    雪晨杰阅读 684评论 0 0
  • [TOC] LiveData LiveData概述 LiveData是一个可观察的数据持有者类。与常规observ...
    雪晨杰阅读 1,106评论 0 8
  • LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵...
    tse1y阅读 3,030评论 0 2
  •   LiveData是一个可被观察的数据持有者类。与常规的Observable不同,LiveData能意识到应用程...
    鹤鹤阅读 47,030评论 6 42
  • 我常常听身边的人说,我好羡慕她有一个可爱的儿子,还有一个幸福的家庭?还有人说,我好羡慕他有一份稳定的工作?我好羡慕...
    冰叶草阅读 527评论 0 5