美文网首页
Jetpack学习(三)——LiveData&ViewModel

Jetpack学习(三)——LiveData&ViewModel

作者: 岁月静好浅笑安然 | 来源:发表于2020-01-14 17:36 被阅读0次

    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;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Jetpack学习(三)——LiveData&ViewModel

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