Android MVVM探索(ViewModel + LiveData + Databinding)

本文是对ViewModel + LiveData + Databinding架构的一些探讨。

  • 关于Databinding :https://developer.android.com/topic/libraries/data-binding
  • 关于LiveData:https://developer.android.com/topic/libraries/architecture/livedata
  • 关于ViewModel:https://developer.android.com/topic/libraries/architecture/viewmodel

直接上代码:

ViewModel:

public class SplshViewModel extends BaseViewModel {
MutableLiveData data = new MutableLiveData();
PosterBean p = new PosterBean();
private DisposableSubscriber disposableSubscriber;

@Override
public void loadData() {
    RetrofitManager.getInstance().createReq(SplashApi.class)
            .getPoster()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new BaseObserver() {
                @Override
                public void onSuccees(PosterBean posterBean) {
                    if (posterBean.getCode() != 0) {
                        getNavigator().showMessage(posterBean.getMessage());
                        return;
                    }
                    p.setCode(posterBean.getCode());
                    p.setData(posterBean.getData());
                    p.setMessage(posterBean.getMessage());
                    data.setValue(p);
                }
                @Override
                public void onFailure(String message) {
                    getNavigator().showMessage(message);
                }
            });

}



public LiveData getData() {
    return data;
}


public void shipOnClick(View view) {
    getNavigator().openMainActivity();
}

public void posterOnClick(View view) {
  
}

public void startCount(int t) {
    disposableSubscriber = new DisposableSubscriber() {
        @Override
        public void onNext(Long aLong) {
            int time = (int) (t - aLong);
            getNavigator().upoutime(time);
        }
        @Override
        public void onError(Throwable t) {
            System.out.println(t.toString());
        }
        @Override
        public void onComplete() {
            getNavigator().openMainActivity();
        }
    };
    Flowable.interval(0, 1, TimeUnit.SECONDS, Schedulers.newThread())
            .take(t)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(disposableSubscriber);
}

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

}

Activity:

public class SplashActivity extends BaseActivity implements SplashNavigator {
private boolean qz = false;
private AlertDialog.Builder normalDialog;
private AlertDialog dialog;

@Override
protected SplshViewModel getViewModel() {
    SplshViewModel splshViewModel = ViewModelProviders.of(this).get(SplshViewModel.class);
    return splshViewModel;
}

@Override
protected int getLayoutResId() {
    return R.layout.activity_splash;
}

@Override
protected void initView() {
    mViewModel.setNavigator(this);
    mViewModel.loadData();
    mViewModel.getData().observe(this, posterBean -> {
        mBinding.setViewModel(mViewModel);
        
    });


}




@Override
protected String getLogTag() {
    return "SplashActivity";
}

@Override
public void showMessage(String msg) {
    showToas(msg);
}

@Override
public void finsh() {
    finish();
}

@Override
public void openMainActivity() {
    if (qz) return;
    startActivity(new Intent(mContext, MainActivity.class));
    finish();
}

@Override
public void loadImage(String url) {
    mBinding.tvSkip.setVisibility(View.VISIBLE);
    Glide.with(mContext).load(url).into(mBinding.ivPoster);
}
}

XML:

 




    
    




    


    




  • 解释

SplshViewModel的loadData()加载数据,getData获取数据,然后activity通过 mViewModel.getData().observe()订阅,数据变化时回调,然后通过 DataBindingUtil.setContentView(this, getLayoutResId());获取到databinding。(这段代码我封装在baseActivity当中了),最后通过mBinding.setViewModel(mViewModel);将数据和databinding绑定,我这里绑定的是viewModel,因为,我点击事件方法写在ViewModel当中的。

  • 问题
    相信这段代码大家都能看懂,但是有一个问题,我想把业务相关的代码放在ViewModel中处理,比如,开屏页展示的广告,我需要判断广告类型,控制跳转具体的页面。我定义了一个SplashNavigator接口,Activity实现该接口,然后通过mViewModel.setNavigator(this); ViewModel持有SplashNavigator,这时候ViewMdel处理完数据,然后通过SplashNavigator提供的具体的方法,具体的去控制页面跳转。这只是一个简单的需求,项目中或许需要更复杂的处理完数据后和activity交互。但是官方文档中说,ViewModel中最好不要持有Activity或者Context的引用,那么我想在ViewModel中处理业务和数据,Activity仅仅只负责更新UI。此时我应该怎么做呢?

我知道大部分数据可以通过DataBinding来和View进行绑定,还可以双向绑定,那比如我要showDialog、showToas、这种时候该怎么做呢?

  • 网上能找到的文章基本你抄我我超你,或者照着官方的几行代码写一小段,完全没有实际意义,希望有大神不吝赐教,共同探讨一下,感谢。

你可能感兴趣的:(Android MVVM探索(ViewModel + LiveData + Databinding))