Android MVVM模式 轻松拥有带状态管理的ViewModel

开发中经常要表示一个数据当前状态,比如加载中、加载错误、空列表。这个时候如果我们每个地方自己去处理就很麻烦,如果我们使用的viewmodel自己就能表示这些状态岂不美哉?

另外数据加载中还经常需要处理取消的逻辑,比如使用rxjava,自动管理disposable就更好了~

说干就干~封装一个BaseViewModel~

package cn.icetower.basebiz.vm;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

/**
 * ViewModel基类,带状态,可设置用来表示主要状态的数据类型。<br>
 *  一个Activity或Fragment中可以有多个ViewModel,使用多个ViewModel的情况可以用来做局部加载和刷新展示。
 *
 *
 * @author renpeng
 * @version 1.0
 * @description
 * @since 2020/8/20
 */
public abstract class BaseViewModel<MainData> extends ViewModel {

    public static final int STATUS_IDLE = 0; //空闲(加载完成)
    public static final int STATUS_LOADING = 1; //加载中
    public static final int STATUS_ERROR = 2;//异常
    public static final int STATUS_EMPTY = 3;//无数据
    public static final int STATUS_CANCEL = 4;//用户取消

    private volatile int status = STATUS_IDLE; //当前viewmodel的主要状态,外部可以通过这个标识来作UI展示
    private CompositeDisposable compositeDisposable;
    protected MutableLiveData<MainData> mainData = new MutableLiveData<>();
    protected int page = 1;//方便子类分布加载时使用


    /**
     * 直接获取到mainData对象,但不进行任何额外的操作
     * @param <T>
     * @return
     */
    public <T> MutableLiveData<MainData> getMainData(){
        return mainData;
    }

    protected void setLoading(){
        setLoading(mainData.getValue());
    }

    protected void setLoading(MainData data){
        this.status = STATUS_LOADING;
        mainData.postValue(data);
    }

    protected void setError(MainData data){
        this.status = STATUS_ERROR;
        mainData.postValue(data);
    }

    protected void setIdle(@NonNull MainData data){
        this.status = STATUS_IDLE;
        mainData.postValue(data);
    }

    /**
     * 加载状态,loading状态下默认会收到上次保存的值
     */
    public boolean isLoading(){
        return this.status == STATUS_LOADING;
    }

    /**
     * 错误状态
     */
    public boolean isError(){
        return this.status == STATUS_ERROR;
    }

    /**
     * 数据量为0
     */
    public boolean isEmpty(){
        return this.status == STATUS_EMPTY;
    }

    /**
     * 空闲状态
     */
    public boolean isIdle(){
        return this.status == STATUS_IDLE;
    }

    public boolean isIdleWithData(){
        return isIdle() && mainData.getValue() != null;
    }

    /**
     * 一般用来设置列表数据大小为0
     * @param data
     */
    protected void setEmpty(MainData data){
        this.status = STATUS_ERROR;
        mainData.postValue(data);
    }

    @Override
    @CallSuper
    protected void onCleared() {
        super.onCleared();
        if(compositeDisposable != null){
            compositeDisposable.dispose();
            compositeDisposable = null;
        }
    }

    public void addDisposable(Disposable disposable){
        if(compositeDisposable == null){
            compositeDisposable = new CompositeDisposable();
        }
        compositeDisposable.add(disposable);
    }



}

另外:一个Actvity或Fragment中可以使用多个viewmodel,用来加载不同部分的数据,可以做局部加载或刷新用,更加方便~

要使用参数可以通过在子类定义成员变量,使用时set赋值,然后在doLoadData中使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值