简化你的列表Adapter

BindingCollectionAdapter

最近看到了这个基于databing的开源库,简单翻译了一下。。。
GitHub地址

一 依赖安装

compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:2.2.0'
compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:2.2.0'

gradle 版本需要在2.3.0以上

二 使用

2.1 单视图

你需要提供items(数据list)和ItemBinding 去绑定数据,应使用ObserableList去自动更新View,当然,如果你不需要该功能也可以使用其他类型的List。
示例ViewModel:

public class ViewModel {
  public final ObservableList items = new ObservableArrayList<>();
  public final ItemBinding itemBinding = ItemBinding.of(BR.item, R.layout.item);
}

然后布局绑定viewModel的items和itemBinding,如果使用RecyclerView需要绑定一个layoutManager(看示例)



    
      
      
      
    

    

    

    

    

集合中的item将会通过ItemBinding绑定到子布局中



    
      
    

    

2.2 多视图

你可以重写onItemBind实现多视图布局,仍使用app:itemBinding绑定数据。

public final OnItemBind onItemBind = new OnItemBind() {
  @Override
  public void onItemBind(ItemBinding itemBinding, int position, String item) {
    itemBinding.set(BR.item, position == 0 ? R.layout.item_header : R.layout.item);
  }
};

如果使用的是ListView,必须使用app:itemTypeCount="@{2}来指定视图类型数量。
注意:如果你不做任何复杂的数据,onItemBind仍会被多次调用,如果你不需要绑定数据,应当使用ItemBinding.VAR_NONE 作为variable的id

2.3 绑定其他变量

可以使用itemBinding.bindExtra(BR.extra, value)来为列表的子布局添加额外的变量,示例为布局额外绑定一个点击事件

public interface OnItemClickListener {
    void onItemClick(String item);
}

OnItemClickListener listener = ...;
ItemBinding itemBinding = ItemBinding.of(BR.item, R.layout.item)
    .bindExtra(BR.listener, listener);

    
      
      
    

    

2.4 额外的Adapter配置

2.4.1 ListView

通过回调为每一个子布局添加id

adapter.setItemIds(new BindingListViewAdapter.ItemIds() {
  @Override
  public long getItemId(int position, T item) {
    return // Calculate item id.
  }
});

或者在布局中通过app:itemIds="@{itemIds}"来绑定。通过设置这个会使hasStableIds 返回true,从而加大内存消耗,
可以通过回调来决定是否启用

adapter.setItemEnabled(new BindingListViewAdapter.ItemEnabled() {
  @Override
  public boolean isEnabled(int position, T item) {
    return // Calculate if item is enabled.
  }
});

或者通过app:itemEnabled="@{itemEnabled}"在布局文件中绑定

2.4.2 ViewPager

通过回调为子页面添加标题

adapter.setPageTitles(new PageTitles() {
  @Override
  public CharSequence getPageTitle(int position, T item) {
    return "Page Title";
  }
});

或者通过 app:pageTitles="@{pageTitles}"为ViewPage绑定标题

2.4.3 RecyclerView

自定义view holders

adapter.setViewHolderFactory(new ViewHolderFactory() {
  @Override
  public RecyclerView.ViewHolder createViewHolder(ViewDataBinding binding) {
    return new MyCustomViewHolder(binding.getRoot());
  }
});

或者通过app:viewHolder="@{viewHolderFactory}" 绑定

2.5 直接操作View

如果你需要直接操作View,你可以通过自定义Adapter来实现

public class MyRecyclerViewAdapter extends BindingRecyclerViewAdapter {

  @Override
  public ViewDataBinding onCreateBinding(LayoutInflater inflater, @LayoutRes int layoutId, ViewGroup viewGroup) {
    ViewDataBinding binding = super.onCreateBinding(inflater, layoutId, viewGroup);
    Log.d(TAG, "created binding: " + binding);
    return binding;
  }

  @Override
  public void onBindBinding(ViewDataBinding binding, int bindingVariable, @LayoutRes int layoutId, int position, T item) {
    super.onBindBinding(binding, bindingVariable, layoutId, position, item);
    Log.d(TAG, "bound binding: " + binding + " at position: " + position);
  }
}

布局文件中绑定adapter


2.6 OnItemBind 助手

这儿有一些OnItemBind的常见的实现

itemBind = new OnItemBindClass<>()
  .map(String.class, BR.name, R.layout.item_name)
  .map(Footer.class, ItemBinding.VAR_NONE, R.layout.item_footer)
  .map(Item.class, new OnItemBind() {
                       @Override
                       public void onItemBind(ItemBinding itemBinding, int position, Item item) {
                         itemBinding.clearExtras()
                                    .set(BR.item, position == 0 ? R.layout.item_header : R.layout.item)
                                    .bindExtra(BR.extra, (list.size() - 1) == position);
                       }
                     })
  .map(Object.class, ItemBinding.VAR_NONE, R.layout.item_other);

OnItemBindModel 是子布局的binding

itemBind = new OnItemBindModel();

public class Model implements ItemBindingModel {
  @Override
  public void onItemBind(ItemBinding itemBinding) {
    itemBinding.set(BR.name, R.layout.item_name);
  }
}

2.7 MergeObservableList

用于融合两个列表

ObservableList data = new ObservableArrayList<>();
MergeObservableList list = new MergeObservableList<>()
  .insertItem("Header")
  .insertList(data)
  .insertItem("Footer");

data.addAll(Arrays.asList("One", "Two"));
// list => ["Header", "One", "Two", "Footer"]
data.remove("One");
// list => ["Header", "Two", "Footer"]

2.8 DiffObservableList

用于列表的更新

DiffObservableList list = new DiffObservableList(new DiffObservableList.Callback() {
    @Override
    public boolean areItemsTheSame(Item oldItem, Item newItem) {
        return oldItem.id.equals(newItem.id);
    }

    @Override
    public boolean areContentsTheSame(Item oldItem, Item newItem) {
        return oldItem.value.equals(newItem.value);
    }
});

list.update(Arrays.asList(new Item("1", "a"), new Item("2", "b1")));
list.update(Arrays.asList(new Item("2", "b2"), new Item("3", "c"), new Item("4", "d"));

线程切换

DiffObservableList list = new DiffObservableList(...);

// On background thread:
DiffUtil.DiffResult diffResult = list.calculateDiff(newItems);

// On main thread:
list.update(newItems, diffResult);

你可能感兴趣的:(简化你的列表Adapter)