美文网首页
JetPack_ViewModel + LiveData +Da

JetPack_ViewModel + LiveData +Da

作者: 老北瓜 | 来源:发表于2020-03-14 21:43 被阅读0次

    使用 ViewModel 将控制器中 ( Activity , Fragment ) 的数据单独抽离出来,并且界面数据会有一个临时的保存,比如旋转屏幕时数据不会丢失

    使用方法:

    导入依赖   implementation    'androidx.lifecycle:lifecycle-extensions:2.2.0'
    

    自定义对应控制器的ViewModel ,

    public class MainViewModel extends ViewModel {
        int number;
    }
    

    在Java 文件中

    public class MainActivity extends AppCompatActivity {
    
        private MainViewModel mainViewModel;
        private TextView textView;
        private Button button;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
          
          // 方法已经过时
          //  mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
            mainViewModel = new ViewProvider(this).get(MainViewModel.class);
    
            textView = findViewById(R.id.textView);
            button = findViewById(R.id.button);
            textView.setText(String.valueOf(mainViewModel.number));
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mainViewModel.number++;
                    textView.setText(String.valueOf(mainViewModel.number));
                }
            });
        }
    }
    

    LiveData : 底层数据改变时,自动通知界面
    实现方法:
    在定义的ViewModel 中 创建 MutableLiveData<T>对象

    public class MainViewModel extends ViewModel {
    
        private MutableLiveData<Integer> number;
    
        public MutableLiveData<Integer> getNumber() {
    
            if (number == null) {
                number = new MutableLiveData<>();
                number.setValue(0);
            }
            return number;
        }
    
        public void setNumber(int num) {
            number.setValue(number.getValue() + num);
        }
    }
    

    在Java文件中使用 liveData.observe()

            // LiveData 的观察者模式
            mainViewModel.getNumber().observe(this, new Observer<Integer>() {
                @Override
                public void onChanged(Integer integer) {
                    textView.setText(String.valueOf(integer));
                }
            });
    
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mainViewModel.setNumber(1);
                }
            });
    

    DataBinding : 将数据绑定到View
    在model 的build.gradle 中添加

    defaultConfig {
           ...
            // 使用databinding
            dataBinding {
                enabled = true
            }
    

    在 view 层 , 将xml 文件convert -> binding layout

    <layout 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">
        <data>
            <variable
                name="viewModel"
                type="com.example.jetpackdemo.MainViewModel" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
    
            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(viewModel.number)}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.535"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.168" />
    
            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->viewModel.setNumber(1)}"
                android:text="@string/button"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.52"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.431" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    
    可以直接引用model中的变量,也可以直接使用model中的函数。
    

    在Java文件中 实例化 DataBinding,使用了databinding,会直接生成一个xml文件名的 ActivityMainBinding文件。

     mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    
            // 给 view 绑定数据
            binding.setViewModel(mainViewModel);
            // 用来观察 LiveData 的更改 ;
            binding.setLifecycleOwner(this);
    

    这样就 ... 嗯 就这样了。

    保存页面数据 SaveInstanceState(), ViewModel 也可以使用这样的方式来保存页面数据,当界面重新创建之间后恢复之前的数据

    public class TestModel extends ViewModel {
        
        private static final String _NUMBER = "TEXT_NUMBER";
        private SavedStateHandle mHandle;
    
        public TestModel(SavedStateHandle handle) {
            this.mHandle = handle;
        }
        
        /**
         * @return 返回值 还是一个  LiveData ;
         */
        public MutableLiveData<Integer> getNumber() {
            /**
             * 系统传递过来的 SavedStateHandle 不会为空,不需要判空
             * 只需要判断是否包含需要的数据
             * 如果没有数据就给他赋一个初始值
             */
            if (!mHandle.contains(_NUMBER)) {
                mHandle.set(_NUMBER, 0);
            }
            return mHandle.getLiveData(_NUMBER);
        }
        
        // set Data
        public void add() {
            getNumber().setValue(getNumber().getValue() + 1);
        }
    }
    

    在java文件中

     testModel = ViewModelProviders.of(this,
                    new SavedStateViewModelFactory(getApplication(), this)).get(TestModel.class);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_test);
            binding.setTest(testModel);
            binding.setLifecycleOwner(this);
    

    在 view层xml文件中设置数据就要 @{data.getNumber()}

    ViewModel 有一个子类 AndroidViewModel,可以在这个类里面 getApplication();

    在livedata 的参数 Observer{ onChanged(PagedList)} pagedlist对象需要绑定一个DataSource, (DataSource的产生又是DataSource.Factory())

    相关文章

      网友评论

          本文标题:JetPack_ViewModel + LiveData +Da

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