mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context)); // + .
<android.support.v7.widget.RecyclerView app:layoutManager="android.support.v7.widget.GridLayoutManager" />
<android.support.v7.widget.RecyclerView app:listConfig="@{viewModel.listConfig}"/>
ListConfig listConfig = new ListConfig.Builder(mAdapter) //.setLayoutManagerProvider(new GridLayoutManagerProvider(mCount, mSpanLookup)) //LinearLayoutManager if not set //.addItemDecoration(new ColorDividerItemDecoration(color, spacing, SPACE_LEFT | SPACE_TOP, false)) .setDefaultDividerEnabled(true) .addOnScrollListener(new OnLoadMoreScrollListener(mCallback)) .setItemAnimator(getItemAnimator()) .setHasFixedSize(true) .setItemTouchHelper(getItemTouchHelper()) .build(context);
public class ListConfig { // Adapter, LayoutManager, ItemAnimator, ItemDecorations, ScrollListeners, // ItemTouchHelper, hasFixedSize private ListConfig(/*params*/) { // init fields } public void applyConfig(final Context context, final RecyclerView recyclerView) { //... apply config } public static class Builder { public Builder(Adapter adapter) {/*set field*/} public Builder setLayoutManagerProvider(LayoutManagerProvider layoutManagerProvider){/*set field*/} public Builder setItemAnimator(ItemAnimator itemAnimator){/*set field*/} public Builder addItemDecoration(ItemDecoration itemDecoration){/*set field*/} public Builder addOnScrollListener(OnScrollListener onScrollListener){/*set field*/} public Builder setHasFixedSize(boolean isFixedSize){/*set field*/} public Builder setDefaultDividerEnabled(boolean isEnabled){/*set field*/} public Builder setDefaultDividerSize(int size){/*set field*/} public Builder setItemTouchHelper(ItemTouchHelper itemTouchHelper){/*set field*/} public ListConfig build(Context context) { /*set default values*/ return new ListConfig(/*params*/); } } public interface LayoutManagerProvider { LayoutManager get(Context context); } }
public class User implements BaseModel { public String name; public String avatar; } public class Location implements BaseModel { public String name; public String image; } public class Advertisement implements BaseModel { public String label; public String image; }
mAdapter = new DelegateAdapter<>( new UserDelegate(actionHandler), // or new ModelItemDelegate(User.class, R.layout.item_user, BR.user), new LocationDelegate(), new AdvertismentDelegate(), // ... );
public class UserDelegate extends ActionAdapterDelegate<BaseModel, ItemUserBinding> { public UserDelegate(final ActionClickListener actionHandler) { super(actionHandler); } @Override public boolean isForViewType(@NonNull final List<BaseModel> items, final int position) { return items.get(position) instanceof User; } @NonNull @Override public BindingHolder<ItemUserBinding> onCreateViewHolder(final ViewGroup parent) { return BindingHolder.newInstance(R.layout.item_user, LayoutInflater.from(parent.getContext()), parent, false); } @Override public void onBindViewHolder(@NonNull final List<BaseModel> items, final int position, @NonNull final BindingHolder<ItemUserBinding> holder) { final User user = (User) items.get(position); holder.getBinding().setUser(user); holder.getBinding().setActionHandler(getActionHandler()); } @Override public long getItemId(final List<BaseModel> items, final int position) { return items.get(position).getId(); } }
public class BindingHolder<VB extends ViewDataBinding> extends RecyclerView.ViewHolder { private VB mBinding; public static <VB extends ViewDataBinding> BindingHolder<VB> newInstance( @LayoutRes int layoutId, LayoutInflater inflater, ViewGroup parent, boolean attachToParent) { final VB vb = DataBindingUtil.inflate(inflater, layoutId, parent, attachToParent); return new BindingHolder<>(vb); } public BindingHolder(VB binding) { super(binding.getRoot()); mBinding = binding; } public VB getBinding() { return mBinding; } }
// new UserDelegate(actionHandler), new ModelItemDelegate(User.class, R.layout.item_user); // or new ModelItemDelegate(R.layout.item_user, BR.model, (item) -> item instance of User);
public class ModelItemDelegate<T> extends BaseListBindingAdapterDelegate<T, ViewDataBinding> { private final int mModelId; private final int mItemLayoutResId; private final ViewTypeClause mViewTypeClause; public ModelItemDelegate(@NonNull Class<? extends T> modelClass, @LayoutRes int itemLayoutResId) { this(itemLayoutResId, BR.model, new SimpleViewTypeClause(modelClass)); } public ModelItemDelegate(@LayoutRes int itemLayoutResId, int modelId, ViewTypeClause viewTypeClause) { mItemLayoutResId = itemLayoutResId; mViewTypeClause = viewTypeClause; mModelId = modelId != 0 ? modelId : BR.model; } @Override public boolean isForViewType(@NonNull List<T> items, int position) { return mViewTypeClause.isForViewType(items, position); } @NonNull @Override public BindingHolder<ViewDataBinding> onCreateViewHolder(ViewGroup parent) { return BindingHolder.newInstance(mItemLayoutResId, LayoutInflater.from(parent.getContext()), parent, false); } @Override public void onBindViewHolder(@NonNull List<T> items, int position, @NonNull BindingHolder<ViewDataBinding> holder) { ViewDataBinding binding = holder.getBinding(); binding.setVariable(mModelId, items.get(position)); binding.executePendingBindings(); } public interface ViewTypeClause { boolean isForViewType(List<?> items, int position); } public static class SimpleViewTypeClause implements ViewTypeClause { private final Class<?> mClass; public SimpleViewTypeClause(@NonNull Class<?> aClass) { mClass = aClass; } @Override public boolean isForViewType(List<?> items, int position) { return mClass.isAssignableFrom(items.get(position).getClass()); } } }
Source: https://habr.com/ru/post/308872/
All Articles