Android-DataBinding使用
1 Nov 2018
最近在学习使用jetpack里的组件,本项目学习DataBinding模块。
DataBinding是在XML中设置要绑定的数据变量,通过ViewModel更新数据。
相关文档:
jetpack官网:https://developer.android.com/jetpack/
data-binding官方文档:
https://developer.android.com/topic/libraries/data-binding/
学习项目:
https://github.com/pulque/DataBinding学习说明:
1.ViewModel,负责更新XML文件中的界面数据。
2.ConstraintLayout,约束布局。
3.RecyclerView,列表显示。
4.cardview,卡片样式。
代码流程:
1.ViewModel
ViewModel的不同之处在于界面布局文件XML。<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"> <data> <variable name="viewmodel" type="com.lizheblogs.databinding.ui.main.MainViewModel" /> <variable name="fragment" type="com.lizheblogs.databinding.ui.main.MainFragment" /> </data> <android.support.constraint.ConstraintLayout android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.main.MainFragment"> <Button android:id="@+id/butCrash" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="@{() -> fragment.onClickCrash()}" android:text="崩溃" /> <Button android:id="@+id/but1" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="@{() -> fragment.onClickMain1()}" android:text="跳转列表测试" app:layout_constraintTop_toBottomOf="@+id/butCrash" /> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{() -> viewmodel.onClickMessage()}" android:text="@{viewmodel.name, default=app}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout> </layout>
解释:
layout标签建立后,AS会生成一个以XML名+Binding的对象,可以用这个对象直接操作XML中的控件。
data标签中是引用的变量和对象
@{}中绑定的数据或者调用的方法。
public final ObservableField<String> name; public MainViewModel() { name = new ObservableField<>(); name.set("123456"); } public void onClickMessage() { name.set("789"); Log.e("===============", "onClickMessage"); }解释:
当set的时候,ObservableField会通知UI更新数据。
2.结合RecyclerView
RecyclerView比ListView更加灵活,绑定数据相类似。需要Adapter和Holder来适配数据。
BaseHolder:
public class BaseHolder extends RecyclerView.ViewHolder { private ViewDataBinding mBinding; BaseHolder(View v) { super(v); mBinding = DataBindingUtil.bind(v); } public void setBinding(int variableId, Object object) { mBinding.setVariable(variableId, object); mBinding.executePendingBindings(); } }解释:
使用ViewDataBinding绑定数据。
BaseAdapter:
public class BaseAdapter<T> extends RecyclerView.Adapter<BaseHolder> { private List<T> listData; private int layoutId; private int variableId; public BaseAdapter(int layoutId, int variableId, List<T> listData) { this.listData = listData; this.variableId = variableId; this.layoutId = layoutId; } @NonNull @Override public BaseHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new BaseHolder(LayoutInflater.from(parent.getContext()) .inflate(layoutId, parent, false)); } @Override public void onBindViewHolder(@NonNull BaseHolder holder, int position) { holder.setBinding(variableId, listData.get(position)); } @Override public int getItemCount() { return listData.size(); } }解释:
使用ViewDataBinding绑定数据。
ListFragment:
public class ListFragment extends Fragment { private ListFragmentBinding binding; public static ListFragment newInstance() { return new ListFragment(); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = DataBindingUtil.inflate(inflater, R.layout.list_fragment, container, false); return binding.getRoot(); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ListViewModel mViewModel = ViewModelProviders.of(this) .get(ListViewModel.class); binding.setViewModel(mViewModel); GridLayoutManager linearLayoutManager = new GridLayoutManager(getContext(), 1); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); binding.recyclerView.setLayoutManager(linearLayoutManager); binding.recyclerView.setItemAnimator(new DefaultItemAnimator()); BaseAdapter<Product> productAdapter = new BaseAdapter<> (R.layout.list_item, BR.product, mViewModel.getArrayList()); mViewModel.setAdapter(productAdapter); binding.recyclerView.setAdapter(productAdapter); } }解释:
ViewModel获取Adapter是为了当数据变化的时候,更新界面。
学习结果:
学习用ViewDataBinding绑定数据,用RecyclerView显示列表数据总结:
ViewModel只是将数据缓存到内存中,退出或崩溃数据不会保留。RecyclerView的点击事件,在viewHolder.itemView中设置。
进阶:
RecyclerView的交互和数据更新。Fragment中的逻辑需要进一步分离。
进阶参考:
https://github.com/googlesamples/android-architecture-components/