Android MVVM探索(ViewModel + LiveD

作者: 一位不愿透露自己姓氏的先生 | 来源:发表于2019-10-25 14:22 被阅读0次

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

    直接上代码:

    ViewModel:

    public class SplshViewModel extends BaseViewModel<SplashNavigator> {
    MutableLiveData<PosterBean> 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<PosterBean>() {
                    @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<PosterBean> getData() {
        return data;
    }
    
    
    public void shipOnClick(View view) {
        getNavigator().openMainActivity();
    }
    
    public void posterOnClick(View view) {
      
    }
    
    public void startCount(int t) {
        disposableSubscriber = new DisposableSubscriber<Long>() {
            @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<ActivitySplashBinding, SplshViewModel> 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:

     <?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"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.xueseng.activity.SplashActivity">
    
    <data>
    
        <import type="android.view.View" />
        <variable
            name="viewModel"
            type="com.xueseng.viewmodel.SplshViewModel" />
    </data>
    
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        >
    
        <ImageView
            android:id="@+id/iv_poster"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/color_white"
            android:scaleType="centerCrop"
            android:onClick="@{viewModel.posterOnClick}"
            android:src="@mipmap/lunchpage" />
    
    
        <TextView
            android:id="@+id/tv_skip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="40dp"
            android:background="@drawable/shape_splah_taks"
            android:paddingLeft="8dp"
            android:paddingTop="3dp"
            android:paddingRight="8dp"
            android:paddingBottom="3dp"
            android:onClick="@{viewModel.shipOnClick}"
            android:text="跳过 3"
            android:visibility="gone" />
    
    </RelativeLayout>
    
    </layout>
    
    • 解释

    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 + LiveD

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