jetpack系列文章:ViewModel源码+最终组合使用

Databinding:单双向数据绑定

Databinding:动态数据更新

Lifecycle讲解

livedata源码分析

ViewModel源码+最终组合使用

前言

ViewModel一般都是和livedata一起使用,主要目的其实就是为了解耦,livedata中通过lifecycle根据生命周期做一些事情,ViewModel控制着数据,结合databinding,相互配合使用,ViewModel控制着数据,通过反射创建并在store中统一进行管理
这里需要说一下,ViewModel在2.1.0之后废弃了ViewModelProviders这个类,统一使用ViewModelProvider,其实吧,说白了就是把ViewModelProviders中的of方法拆开了。

老版本的创建

之前是这么用的,眼熟吧。

TestViewModle viewModle = ViewModelProviders.of(this).get(TestViewModle.class);

新版本的创建

废弃后通过ViewModelProvider类实现:
通过构造方法可以看到需要传入一个owner和一个工厂,有啥用呢
1、owner用来得到一个ViewModelStore,意如其名,就是用来管理ViewModel的
2、factory当然就是为了制造ViewModel的了

ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory;

现在的生成方法:
1、为什么要通过AndroidViewModelFactory,因为老版本的of中就是用的这个方法。。。这个理由是不是很骚气。。。
2、使用get方法去获取modle对象

TestViewModle viewModle = new ViewModelProvider(this , ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(TestViewModle.class);

get方法其实就是为了复用ViewModel,ViewModel都是有构造中传入的owner成成的store统一管理的,最后调用了create方法,通过反射创建出自定义的TestViewModle对象,并返回。

public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
    ViewModel viewModel = mViewModelStore.get(key);
    if (modelClass.isInstance(viewModel)) {
        return (T) viewModel;
    } else {
        if (viewModel != null) {
        }
    }
    if (mFactory instanceof KeyedFactory) {
        viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
    } else {
        viewModel = (mFactory).create(modelClass);
    }
    mViewModelStore.put(key, viewModel);
    return (T) viewModel;
}

viewmodel

这个onCleared可以用来当viewmodel不在被使用的时候,做一些销毁的工作,防止内存泄漏

class TestViewModle extends ViewModel {
    @Override
    protected void onCleared() {
        super.onCleared();
    }
}

最后来一个组合使用

布局文件

data中的三个类:1、bean类;2、交互类,一般如点击事件;3、请求+数据处理操作类;算是标配吧;
这个bean类可以写在布局文件里,也可以在ViewModel中通过泛型创建,方便拓展

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="user"
            type="com.example.myapplication.bean.User" />
        <variable
            name="present"
            type="com.example.myapplication.UserPresent" />
        <variable
            name="viewmodel"
            type="com.example.myapplication.UserViewModel" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/xiaoguo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="登录界面" />
//把数据绑定到viewmodel中的requestData中去,等待网络请求使用
        <EditText
            android:id="@+id/edit_text"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:afterTextChanged="@{viewmodel.afterTextChange}" 
            android:hint="输入框"/>
        <Button
            android:id="@+id/first_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{(view)->present.myClick(view ,user)}" //点击事件
            android:text="@{user.firstName}" />
        <Button
            android:id="@+id/last_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{(view)->present.myClick(view ,user)}"//点击事件
            android:text="@{user.lastName}" />
    </LinearLayout>
</layout>

UserViewModel类

1、这个类用来作为数据控制类,桥接view和model,通过livedata操作数据
2、布局中EditText输入的数据保存到requestData 中,在调用requestData()方法的时候,将结果通过userData传递给view层

public class UserViewModel extends ViewModel {

	MutableLiveData<String> requestData = new MutableLiveData<>();//保存文本输入的数据
	MutableLiveData<User> userData = new MutableLiveData<>();//将数据传给view层
	
	//模拟网络请求
	public void requestData() {
	    User user = new User("jiang", requestData.getValue(), 100);
	    userData.setValue(user);
	}
	
	@Override
	protected void onCleared() {
	    super.onCleared();
	}
	//接受输入的数据保存到requestData中去,等待请求使用
	public void afterTextChange(Editable s) {
	    requestData.setValue(s.toString());
	}
}

主类

//实现点击类UserPresent
public class MainActivity extends AppCompatActivity implements UserPresent {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    //创建dataBinding
	    dbBinding = DataBindingUtil.setContentView(this, R.layout.activity_db);
		//绑定点击事件
	    dbBinding.setPresent(this);
	    //初始化bean类数据并绑定到dataBinding里
	    dbBinding.setUser(new User("点击请求","结果",100));
	    //创建并绑定viewmodel
	    dbBinding.setViewmodel(new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(UserViewModel.class));
	    //创建viewmodel中的数据监听器并绑定到dataBinding中去
	    dbBinding.getViewmodel().userData.observe(this, new Observer<User>() {
	        @Override
	        public void onChanged(User user) {
	        //如果数据有修改,更新要改的地方。
	            dbBinding.getUser().setLastName(user.getLastName());
	        }
	    });
	}

	//重写点击方法,调用请求
	@Override
	public void myClick(View view, User user) {
    	dbBinding.getViewmodel().requestData();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值