AndroidX设计架构MVVM之DataBinding+ViewModel+LiveData

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/lylddingHFFW/article/details/102657746

AndroidX设计架构MVVM之DataBinding+ViewModel+LiveData

原文

AndroidX设计架构MVVM之ViewModel创建流程原理分析
AndroidX设计架构MVVM之ViewModel生命周期分析
AndroidX设计架构MVVM之LiveDatal生命周期及数据监听分析
AndroidX设计架构MVVM之DataBinding搭配LiveData的分析
AndroidX设计架构MVVM之DataBinding+ViewModel+LiveData

环境各版本:
android studio 3.5.1
android gradle plugin version 3.5.1
gradle version 5.4.1
ViewModel 2.1.0
LiveData 2.1.0

整体来说MVVM架构的搭建依赖于Android的现有的组件,搭建还是非常简单的,个人觉得最好还是要了解各组件的原理(可参考上边链接),提供的Demo非常简单,通过组件化实现,可参考测试Demo-design-component中modulemvvm

在这里插入图片描述

1:启用databinding

android {
    。。。。。。
    //开启DataBinding
    dataBinding {
        enabled true
    }
 }

2: 导入需要的组件ViewModel 和 LiveData

在项目的build.gradle中加入如下仓库

allprojects {
    repositories {
        google()
        jcenter()
    }
}

加入具体组件详细见注释,可以根据需要选择

dependencies {
    //使用的版本
    def lifecycle_version = "2.1.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}

3:写自己的代码,wtf

用户UserBean

public class UserBean {
    private String name;
    private String age;

    private UserBean() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public static final class UserBeanBuilder {
        private String name;
        private String age;

        private UserBeanBuilder() {
        }

        public static UserBeanBuilder newBuilder() {
            return new UserBeanBuilder();
        }

        public UserBeanBuilder setName(String name) {
            this.name = name;
            return this;
        }

        public UserBeanBuilder setAge(String age) {
            this.age = age;
            return this;
        }

        public UserBean build() {
            UserBean userBean = new UserBean();
            userBean.age = this.age;
            userBean.name = this.name;
            return userBean;
        }
    }
}

用户的ViewModel

public class VMUser extends BaseViewModel {
    //live data
    private MutableLiveData<UserBean> mUserInfo;

    public VMUser(@NonNull Application application) {
        super(application);
        mUserInfo = new MutableLiveData<>();
    }

    public MutableLiveData<UserBean> getUserInfo() {
        return mUserInfo;
    }

    public void loadUserInfo() {
        //模拟网络加载
        MainLooper.getInstance().postDelayed(new Runnable() {
            @Override
            public void run() {
                mUserInfo.setValue(UserBean.UserBeanBuilder.newBuilder().setName("我是live data").setAge("12").build());
            }
        }, 500);
    }

   public void getWeatherInfo(String city) {
        MvvmNetWork.getInstance().getWeatherInfo(city)
                .compose(RxjavaUtils.<BaseEntity<Weather>>io2main())
                .as(this.<BaseEntity<Weather>>bindLifecycle())
                .subscribe(new BaseObserver<Weather>() {
                    @Override
                    public void onSuccess(BaseEntity<Weather> data) {

                    }

                    @Override
                    public void onFailure(int code, Throwable throwable) {

                    }
                });
    }
}

展示用户信息的View

//各View的父类
public abstract class AbstractBaseMvvmActivity<V extends ViewDataBinding, VM extends BaseViewModel> extends AppCompatActivity {
    protected V mBinding;
    protected VM mViewModel;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, getContentViewId());
        if (getVmClass() == null) {
            LogUtils.e("getVmClass() == null");
        } else {
            mViewModel = ViewModelProviders.of(this).get(getVmClass());
            //防止Rxjava使用时的内存泄漏
            getLifecycle().addObserver(mViewModel);
        }
        //为livedata添加生命周期
        mBinding.setLifecycleOwner(this);
        init();
    }

    protected abstract int getContentViewId();

    protected abstract Class<VM> getVmClass();

    protected abstract void init();

    protected <T> AutoDisposeConverter<T> bindLifecycle() {
        return AutoDisposeUtil.bindLifecycle(this);
    }

    public V getBinding() {
        return mBinding;
    }

    public VM getViewModel() {
        if (mViewModel == null) {
            throw new NullPointerException("mViewModel==null");
        }
        return mViewModel;
    }
}


//展示用户信息的View
public class MvvmMainActivity extends AbstractBaseMvvmActivity<MvvmActivityMainBinding, VMUser> implements View.OnClickListener {

    @Override
    protected int getContentViewId() {
        return R.layout.mvvm_activity_main;
    }

    @Override
    protected Class<VMUser> getVmClass() {
        return VMUser.class;
    }

    @Override
    protected void init() {
     
        getViewModel().getUserInfo().setValue(UserBean.UserBeanBuilder.newBuilder().setName("live data init").setAge("0").build());
        //设置绑定数据
        getBinding().setVMUser(getViewModel());


        //添加点击事件
        getBinding().setEventListener(this);

//        //live data 的数据监听
//        getViewModel().getUserInfo().observe(this, new Observer<UserBean>() {
//            @Override
//            public void onChanged(UserBean userBean) {
//                Toast.makeText(MvvmMainActivity.this, userBean.getName(), Toast.LENGTH_SHORT).show();
//            }
//        });
    }
    
    @Override
    public void onClick(View view) {
        LogUtils.e("haaoaha");
        if (view.getId() == R.id.title) {
           //点击加载用户数据
            getViewModel().loadUserInfo();
        }
    }
}

mvvm_activity_main.xml

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

    <data>

        <variable
            name="userNoLive"
            type="com.lyldding.modulemvvm.bean.UserNoLiveBean" />

        <variable
            name="vMUser"
            type="com.lyldding.modulemvvm.viewmodel.VMUser" />

        <variable
            name="eventListener"
            type="com.lyldding.modulemvvm.MvvmMainActivity" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/title"
            style="@style/Text_Style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{eventListener::onClick}"
            android:text="获取用户信息"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <!-- data binding 示例-->
        <TextView
            android:id="@+id/name_no_live"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="50dp"
            android:text="@{userNoLive.name}"
            app:layout_constraintBottom_toTopOf="@id/age_no_live"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />


        <TextView
            android:id="@+id/age_no_live"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="50dp"
            android:text="@{userNoLive.age}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toTopOf="@id/title" />


        <!--live data 示例-->
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="@{vMUser.userInfo.name}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/title" />

        <TextView
            android:id="@+id/age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="@{vMUser.userInfo.age}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/name" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

猜你喜欢

转载自blog.csdn.net/lylddingHFFW/article/details/102657746