600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > android DataBind LiveData ViewModel 使用详解

android DataBind LiveData ViewModel 使用详解

时间:2020-08-30 16:51:26

相关推荐

android DataBind  LiveData  ViewModel 使用详解

1.导入android x ,升级 版本到28

implementation 'androidx.appcompat:appcompat:1.0.0'def room_version = "2.2.5"implementation "androidx.room:room-runtime:$room_version"kapt "androidx.room:room-compiler:$room_version"def lifecycle_version = "2.2.0"def arch_version = "2.1.0"implementation "androidx.recyclerview:recyclerview:1.1.0"// ViewModelimplementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"// LiveDataimplementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"// Saved state module for ViewModelimplementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"// Annotation processorannotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"// alternately - if using Java8, use the following instead of lifecycle-compilerimplementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"// optional - helpers for implementing LifecycleOwner in a Serviceimplementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"// optional - ProcessLifecycleOwner provides a lifecycle for the whole application processimplementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

没什么好说的,这些基本上是迁移androidx 需要的库,你要把项目中的appcomt 库的引用去掉。

compileSdkVersion 28

提升编译版本,因为有些androidx 的依赖库只能在28上。

2.替换所有的support 包 为android X

androidx.fragment.app.Fragment

fragment 只是举例的一个类而已,有挺多类的,比如AppCompatActivty…

只要是替换成androidX 找不到的类,基本上都要换路径。

3.写一个ViewModel,里面包含LiveData

package com.example.viewModel;import com.example.database.UserDBManager;import com.example.rom.UseDao;import com.example.rom.User;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Executors;import androidx.lifecycle.LiveData;import androidx.lifecycle.MutableLiveData;import androidx.lifecycle.ViewModel;/*** =======================================================================================* 作 者:caoxinyu* 创建日期:/3/20.* 类的作用:* 修订历史:* =======================================================================================*/public class UserViewModel extends ViewModel {private MutableLiveData<List<User>> users;public LiveData<List<User>> getUsers() {if (users == null) {users = new MutableLiveData<>(new ArrayList<>());}final List<User> value = users.getValue();Thread thread = Executors.defaultThreadFactory().newThread(new Runnable() {@Overridepublic void run() {UseDao useDao = UserDBManager.getInstance().getUseDao();List<User> usersAll = useDao.queryAll();if (value != null) {value.addAll(usersAll);}users.postValue(value);}});thread.start();return users;}}

ViewModel 是和activity 生命明周期绑定的一个类,里面一般有个字段,是LiveData,就像我上面写的一样。

一般获取方式为:

UserModel userModel = new ViewModelProvider(requireActivity()).get(UserModel.class);

具体可以看上面贴出来的类。

4.使用DataBing

首先在xml 最外加 标签,里面的 可以对应你写的ViewModel

<layout xmlns:app="/apk/res-auto"><data><import type="android.view.View" alias="View"/><variablename="viewmodel"type="com.example.viewModel.UserViewModel" /><variablename="btName"type="String" /><variablename="show"type="boolean"/><variablename="clickShow"type="android.view.View.OnClickListener"/></data><FrameLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.fragment.RoomFragment"><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.fragment.IOTestFragment"><Buttonandroid:id="@+id/add"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="增加" /><TextViewandroid:id="@+id/useName"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@{viewmodel.users[0] !=null ? viewmodel.users[0].useName:@string/loading,default = @string/loading}"/><Buttonandroid:id="@+id/test_bt"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@{btName}" /><Buttonandroid:id="@+id/test_bt_show"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="测试显示"app:isGone="@{!show}"android:visibility="@{show?View.VISIBLE:View.GONE}"/><Buttonandroid:id="@+id/click"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="@{clickShow}"android:text="点击" /></LinearLayout></FrameLayout></layout>

databing 在xml 的具体写法,可以百度看下,这里先不贴了。挺多种的,或者有时间我写一篇。

6.在activity 或者 fragment 里面 使用Databing数据

// Inflate the layout for this fragmentFragmentRoomTestBinding fragmentRoomTestBinding = FragmentRoomTestBinding.inflate(inflater, container, false);UserViewModel userViewModel = new ViewModelProvider(this).get(UserViewModel.class);fragmentRoomTestBinding.setAddUser(new View.OnClickListener() {@Overridepublic void onClick(View v) {UserDBManager.getInstance().insertTestUser();userViewModel.getUsers();}});LiveData<List<User>> users = userViewModel.getUsers();mUserList = new ArrayList<>();List<User> userList = users.getValue();if (userList != null) {mUserList.addAll(userList);}RecyclerView recycleView = fragmentRoomTestBinding.recycleView;recycleView.setLayoutManager(new LinearLayoutManager(getContext()));UserAdapter adapter = new UserAdapter(mUserList, BR.itemInfo);fragmentRoomTestBinding.setUserIsEmpty(mUserList.isEmpty());users.observe(this, new Observer<List<User>>() {@Overridepublic void onChanged(List<User> users) {mUserList.clear();mUserList.addAll(users);adapter.notifyDataSetChanged();fragmentRoomTestBinding.setUserIsEmpty(users.isEmpty());}});recycleView.setAdapter(adapter);

原理:

1.线程切换问题

当我的liveData 更新之后,如果是在子线程更新的,那么回调的时候,框架是怎么切换到主线程的?

ViewDataBing 里面有两种方法: ViewDataBing 的时候,生成一个handler 保存一下。 mUIThreadHandler = new Handler(Looper.myLooper()); 需要用的时候用handler postRunable 就可以解决

第二种是 Choreographer,这个是databing 默认的方式:

mChoreographer = Choreographer.getInstance();mFrameCallback = new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {mRebindRunnable.run();}};mChoreographer.postFrameCallback(mFrameCallback);

2. 为什么可以监听到viewMode 的 变化?

androidx.databinding.ViewDataBinding.LiveDataListener

/*** Method object extracted out to attach a listener to a bound LiveData object.*/private static final CreateWeakListener CREATE_LIVE_DATA_LISTENER = new CreateWeakListener() {@Overridepublic WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {return new LiveDataListener(viewDataBinding, localFieldId).getListener();}};

你会看到,androidx.databinding.ViewDataBinding这个类里面,CREATE_LIVE_DATA_LISTENER 会给所有的ViewMode 里面的LiveData 对象 设置一个监听,当ViewModel 里面的LiveData 对象的值,变化了,那么databinding 就会更新UI.

3.根据xml 生成的dataBing在哪里?

会有两个,一个是基础类,叫做bind,一个叫做impl.基本上更新UI的代码,都在impl里面。executeBindings 方法会真正的调用绑定,比如TextView. setText

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。