可用于绑定Activity/Fragement等,类似于ButterKnife,好处在于把Activity的逻辑与布局的实现彻底分离,布局相关逻辑全部转移到XXXViewdataBindng中。
而且DataBinding比ButterKnife效率高
DiffUtil是support-v7:24.2.0推出的工具,用来寻找新旧两个数据集的最小变化量,主要使用场景是recycleView的更新,针对RecycleView全局更新的主要缺点:
通过DiffUtil能轻松实现recycleView的差量刷新。
主要使用方式如下:
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return mProductList.size();
}
@Override
public int getNewListSize() {
return productList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {//通过唯一标识判断是否同一数据
return mProductList.get(oldItemPosition).getId() ==
productList.get(newItemPosition).getId();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {//若是同一数据,再比较它内部有没有更新
Product newProduct = productList.get(newItemPosition);
Product oldProduct = mProductList.get(oldItemPosition);
return newProduct.getId() == oldProduct.getId()
&& Objects.equals(newProduct.getDescription(), oldProduct.getDescription())
&& Objects.equals(newProduct.getName(), oldProduct.getName())
&& newProduct.getPrice() == oldProduct.getPrice();
//上面一般情况可以在在实体类中实现equal接口,然后直接return o1.equals(o2)
}
});
mProductList = productList;
result.dispatchUpdatesTo(this);
使用以上的方式可以通过diffResult.dispatchUpdatesTo(adapter)函数实现刷新指定项,如果想做得更细,只刷新指定项中某个textView,imageView等也是可以,主要通过以下两个接口实现:
DiffUtil.Callback
的 public Object getChangePayload(int oldItemPosition, int newItemPosition)
RecyclerView.Adapter
的 public void onBindViewHolder(VH holder, int position, List
当一个item中包含多个view,比如item中有图片但我只想刷新某个textView,这种方式还是能提高性能的,这里不细讲。
LiveData是一个可被观察的数据持有类,与一般的Observer不同的是,LiveData能意识到应用程序组件的生命周期变化,其优点主要有:
· 确保UI符合数据状态
LiveData遵循观察者模式。 当生命周期状态改变时,LiveData会向Observer发出通知。 您可以把更新UI的代码合并在这些Observer对象中。不必去考虑导致数据变化的各个时机,每次数据有变化,Observer都会去更新UI。
· 没有内存泄漏
Observer会绑定具有生命周期的对象,并在这个绑定的对象被销毁后自行清理。
· 不会因停止Activity而发生崩溃
如果Observer的生命周期处于非活跃状态,例如在后退堆栈中的Activity,就不会收到任何LiveData事件的通知。
· 不需要手动处理生命周期
UI组件只需要去观察相关数据,不需要手动去停止或恢复观察。LiveData会进行自动管理这些事情,因为在观察时,它会感知到相应组件的生命周期变化。
· 始终保持最新的数据
如果一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据。 例如,后台Activity在返回到前台后立即收到最新数据。
· 正确应对配置更改
如果一个Activity或Fragment由于配置更改(如设备旋转)而重新创建,它会立即收到最新的可用数据。
您可以使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享。LiveData对象一旦连接到系统服务,任何需要该资源的Observer都只需观察这个LiveData对象。
一般用法:
public class ProductListFragment extends Fragment {
…..
private void subscribeUi(ProductListViewModel viewModel) { // Update the list when the data changes
LiveData> liveData= viewModel.getProducts();
//第一个参数是LifecycleOwner接口的实现类(Activity,Fragment等)
//关联liveData与观察者,匿名的Observer有Fragment的引用,当liveData更新
//实际上是liveData->通知Observer->通知Fragment liveData.observe(this, new Observer>() {
@Override public void onChanged(@Nullable ListmyProducts) { if (myProducts != null) { mBinding.setIsLoading(false); mProductAdapter.setProductList(myProducts); } else { mBinding.setIsLoading(true); } mBinding.executePendingBindings(); } }); }
//在某个地方,比如网络上拉取到数据,执行
//viewModel.getProducts().setValue(….)即可通知Fragment更新
}