/** * Just a marker for progress header/footer. */ public class ProgressVo { }
public class AdVo { private String title; private String description; // Getters, Setters, Builder, etc. }
public class UserVo { private String firstName; private String lastName; private String age; // Getters, Setters, Builder, etc. }
private static final int TYPE_PROGRESS = 10; private static final int TYPE_AD = 20; private static final int TYPE_USER = 30;
@Override public int getItemViewType(int position) { Object item = itemList.get(position); if (item instanceof ProgressVo) { return TYPE_PROGRESS; } else if (item instanceof AdVo) { return TYPE_AD; } else if (item instanceof UserVo) { return TYPE_USER; } else { throw new NoSuchRecyclerItemTypeException(); } }
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == TYPE_PROGRESS) { View view = inflater.inflate(R.layout.cell_progress, parent, false); return new UsersRecyclerAdapter.ProgressViewHolder(view); } else if (viewType == TYPE_AD) { View view = inflater.inflate(R.layout.cell_ad, parent, false); return new UsersRecyclerAdapter.AdViewHolder(view); } else if (viewType == TYPE_USER) { View view = inflater.inflate(R.layout.cell_user, parent, false); return new UsersRecyclerAdapter.UserViewHolder(view); } else { throw new NoSuchRecyclerViewTypeException(); } }
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof ProgressViewHolder) { // Do nothing. } else if (holder instanceof AdViewHolder) { ((AdViewHolder) holder).bind((AdVo) itemList.get(position)); } else if (holder instanceof UserViewHolder) { ((UserViewHolder) holder).bind((UserVo) itemList.get(position)); } }
public class UsersUglyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int TYPE_PROGRESS = 10; private static final int TYPE_AD = 20; private static final int TYPE_USER = 30; private List itemList = new ArrayList(); public UsersUglyRecyclerAdapter() { itemList.add(new ProgressVo()); } @Override public int getItemViewType(int position) { Object item = itemList.get(position); if (item instanceof ProgressVo) { return TYPE_PROGRESS; } else if (item instanceof AdVo) { return TYPE_AD; } else if (item instanceof UserVo) { return TYPE_USER; } else { throw new NoSuchRecyclerItemTypeException(); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == TYPE_PROGRESS) { View view = inflater.inflate(R.layout.cell_progress, parent, false); return new UsersRecyclerAdapter.ProgressViewHolder(view); } else if (viewType == TYPE_AD) { View view = inflater.inflate(R.layout.cell_ad, parent, false); return new UsersRecyclerAdapter.AdViewHolder(view); } else if (viewType == TYPE_USER) { View view = inflater.inflate(R.layout.cell_user, parent, false); return new UsersRecyclerAdapter.UserViewHolder(view); } else { throw new NoSuchRecyclerViewTypeException(); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof ProgressViewHolder) { // Do nothing. } else if (holder instanceof AdViewHolder) { ((AdViewHolder) holder).bind((AdVo) itemList.get(position)); } else if (holder instanceof UserViewHolder) { ((UserViewHolder) holder).bind((UserVo) itemList.get(position)); } } @Override public int getItemCount() { return itemList.size(); } public void setUsers(List<UserVo> users) { itemList.clear(); itemList.addAll(users); decorateItemList(); notifyDataSetChanged(); } private void decorateItemList() { int listSize = itemList.size(); int shift = 0; for (int i = 1; i < listSize; i++) { if (i % 7 == 0) { itemList.add(i + shift, new AdVo()); shift++; } } itemList.add(new ProgressVo()); } protected static class ProgressViewHolder extends RecyclerView.ViewHolder { public ProgressViewHolder(View itemView) { super(itemView); } } protected static class AdViewHolder extends RecyclerView.ViewHolder { public AdViewHolder(View itemView) { super(itemView); } public void bind(AdVo ad) { // Bind ad... } } protected static class UserViewHolder extends RecyclerView.ViewHolder { public UserViewHolder(View itemView) { super(itemView); } public void bind(UserVo user) { // Bind user... } } }
@Override public int getItemViewType(int position) { return CellType.get(itemList.get(position)).type(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return CellType.get(viewType).viewHolder(parent); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { CellType.get(itemList.get(position)).bind(holder, itemList.get(position)); }
private enum CellType { PROGRESS, AD, USER }
private enum CellType { PROGRESS { @Override int type() { return R.layout.cell_progress; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_progress, parent, false); return new ProgressViewHolder(view); } }, AD { @Override int type() { return R.layout.cell_ad; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_ad, parent, false); return new AdViewHolder(view); } }, USER { @Override int type() { return R.layout.cell_user; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_user, parent, false); return new UserViewHolder(view); } }; abstract int type(); abstract RecyclerView.ViewHolder viewHolder(ViewGroup parent); }
private enum CellType { PROGRESS { @Override boolean is(Object item) { return item instanceof ProgressVo; } ... }, AD { @Override boolean is(Object item) { return item instanceof AdVo; } ... }, USER { @Override boolean is(Object item) { return item instanceof UserVo; } ... }; static CellType get(Object item) { for (CellType cellType : CellType.values()) { if (cellType.is(item)) { return cellType; } } throw new NoSuchRecyclerItemTypeException(); } static CellType get(int viewType) { for (CellType cellType : CellType.values()) { if (cellType.type() == viewType) { return cellType; } } throw new NoSuchRecyclerViewTypeException(); } abstract boolean is(Object item); ... }
private enum CellType { PROGRESS { ... @Override void bind(RecyclerView.ViewHolder holder, Object item) { // Do nothing. } }, AD { ... @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { AdViewHolder adViewHolder = (AdViewHolder) holder; AdVo ad = (AdVo) item; adViewHolder.bind(ad); } catch (ClassCastException e) { L.printStackTrace(e); } } }, USER { ... @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { UserViewHolder userViewHolder = (UserViewHolder) holder; UserVo user = (UserVo) item; userViewHolder.bind(user); } catch (ClassCastException e) { L.printStackTrace(e); } } }; ... abstract void bind(RecyclerView.ViewHolder holder, Object item); }
public class UsersRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List itemList = new ArrayList(); public UsersRecyclerAdapter() { itemList.add(new ProgressVo()); } @Override public int getItemViewType(int position) { return CellType.get(itemList.get(position)).type(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return CellType.get(viewType).viewHolder(parent); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { Object item = itemList.get(position); CellType.get(item).bind(holder, item); } @Override public int getItemCount() { return itemList.size(); } public void setUsers(List<UserVo> users) { itemList.clear(); itemList.addAll(users); decorateItemList(); notifyDataSetChanged(); } private void decorateItemList() { int listSize = itemList.size(); int shift = 0; for (int i = 1; i < listSize; i++) { if (i % 7 == 0) { itemList.add(i + shift, new AdVo()); shift++; } } itemList.add(new ProgressVo()); } private enum CellType { PROGRESS { @Override boolean is(Object item) { return item instanceof ProgressVo; } @Override int type() { return R.layout.cell_progress; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_progress, parent, false); return new ProgressViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { // Do nothing. } }, AD { @Override boolean is(Object item) { return item instanceof AdVo; } @Override int type() { return R.layout.cell_ad; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_ad, parent, false); return new AdViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { AdViewHolder adViewHolder = (AdViewHolder) holder; AdVo ad = (AdVo) item; adViewHolder.bind(ad); } catch (ClassCastException e) { L.printStackTrace(e); } } }, USER { @Override boolean is(Object item) { return item instanceof UserVo; } @Override int type() { return R.layout.cell_user; } @Override RecyclerView.ViewHolder viewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_user, parent, false); return new UserViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { UserViewHolder userViewHolder = (UserViewHolder) holder; UserVo user = (UserVo) item; userViewHolder.bind(user); } catch (ClassCastException e) { L.printStackTrace(e); } } }; static CellType get(Object item) { for (CellType cellType : CellType.values()) { if (cellType.is(item)) { return cellType; } } throw new NoSuchRecyclerItemTypeException(); } static CellType get(int viewType) { for (CellType cellType : CellType.values()) { if (cellType.type() == viewType) { return cellType; } } throw new NoSuchRecyclerViewTypeException(); } abstract boolean is(Object item); abstract int type(); abstract RecyclerView.ViewHolder viewHolder(ViewGroup parent); abstract void bind(RecyclerView.ViewHolder holder, Object item); } protected static class ProgressViewHolder extends RecyclerView.ViewHolder { public ProgressViewHolder(View itemView) { super(itemView); } } protected static class AdViewHolder extends RecyclerView.ViewHolder { public AdViewHolder(View itemView) { super(itemView); } public void bind(AdVo ad) { // Bind ad... } } protected static class UserViewHolder extends RecyclerView.ViewHolder { public UserViewHolder(View itemView) { super(itemView); } public void bind(UserVo user) { // Bind user... } } }
private enum CellType { ... static Map<Class, CellType> typeTable = new HashMap<>(); static { typeTable.put(ProgressVo.class, PROGRESS); typeTable.put(AdVo.class, AD); typeTable.put(UserVo.class, USER); } static CellType get(Object item) { return typeTable.get(item.getClass()); } … }
private static final int TYPE_PROGRESS = 10; private static final int TYPE_AD = 20; private static final int TYPE_USER = 30; @Override public int getItemViewType(int position) { Object item = itemList.get(position); if (item instanceof ProgressVo) { return TYPE_PROGRESS; } else if (item instanceof AdVo) { return TYPE_AD; } else if (item instanceof UserVo) { return TYPE_USER; } else { throw new NoSuchRecyclerItemTypeException(); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == TYPE_PROGRESS) { View view = inflater.inflate(R.layout.cell_progress, parent, false); return new UsersRecyclerAdapter.ProgressViewHolder(view); } else if (viewType == TYPE_AD) { View view = inflater.inflate(R.layout.cell_ad, parent, false); return new UsersRecyclerAdapter.AdViewHolder(view); } else if (viewType == TYPE_USER) { View view = inflater.inflate(R.layout.cell_user, parent, false); return new UsersRecyclerAdapter.UserViewHolder(view); } else { throw new NoSuchRecyclerViewTypeException(); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof ProgressViewHolder) { // Do nothing. } else if (holder instanceof AdViewHolder) { ((AdViewHolder) holder).bind((AdVo) itemList.get(position)); } else if (holder instanceof UserViewHolder) { ((UserViewHolder) holder).bind((UserVo) itemList.get(position)); } }
@Override public int getItemViewType(int position) { return CellType.get(itemList.get(position)).type(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return CellType.get(viewType).holder(parent); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { Object item = itemList.get(position); CellType.get(item).bind(holder, item); } private enum CellType { PROGRESS { @Override boolean is(Object item) { return item instanceof ProgressVo; } @Override int type() { return R.layout.cell_progress; } @Override RecyclerView.ViewHolder holder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_progress, parent, false); return new ProgressViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { // Do nothing. } }, AD { @Override boolean is(Object item) { return item instanceof AdVo; } @Override int type() { return R.layout.cell_ad; } @Override RecyclerView.ViewHolder holder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_ad, parent, false); return new AdViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { AdViewHolder adViewHolder = (AdViewHolder) holder; AdVo ad = (AdVo) item; adViewHolder.bind(ad); } catch (ClassCastException e) { L.printStackTrace(e); } } }, USER { @Override boolean is(Object item) { return item instanceof UserVo; } @Override int type() { return R.layout.cell_user; } @Override RecyclerView.ViewHolder holder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_user, parent, false); return new UserViewHolder(view); } @Override void bind(RecyclerView.ViewHolder holder, Object item) { try { UserViewHolder userViewHolder = (UserViewHolder) holder; UserVo user = (UserVo) item; userViewHolder.bind(user); } catch (ClassCastException e) { L.printStackTrace(e); } } }; static CellType get(Object item) { for (CellType cellType : CellType.values()) { if (cellType.is(item)) { return cellType; } } throw new NoSuchRecyclerItemTypeException(); } static CellType get(int viewType) { for (CellType cellType : CellType.values()) { if (cellType.type() == viewType) { return cellType; } } throw new NoSuchRecyclerViewTypeException(); } abstract boolean is(Object item); abstract int type(); abstract RecyclerView.ViewHolder holder(ViewGroup parent); abstract void bind(RecyclerView.ViewHolder holder, Object item); }
public class UsersArbitraryCellAdapter extends ArbitraryCellAdapter { private ProgressArbitraryCell progressArbitraryCell = new ProgressArbitraryCell(); private AdArbitraryCell adArbitraryCell = new AdArbitraryCell(); private UserArbitraryCell userArbitraryCell = new UserArbitraryCell(); public UsersArbitraryCellAdapter() { arbitraryCellSelector.addCell(progressArbitraryCell); arbitraryCellSelector.addCell(adArbitraryCell); arbitraryCellSelector.addCell(userArbitraryCell); } public Observable<AdVo> asAdObservable() { return adArbitraryCell.asAdObservable(); } public Observable<UserVo> asUserObservable() { return userArbitraryCell.asUserObservable(); } // Set Users, Ads, Progress... } public abstract class ArbitraryCellAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected ArbitraryCellSelector arbitraryCellSelector = new ArbitraryCellSelector(); protected List itemList = new ArrayList(); @Override public final int getItemViewType(int position) { return arbitraryCellSelector.getCell(itemList.get(position)).type(); } @Override public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return arbitraryCellSelector.getCell(viewType).holder(parent); } @Override public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { Object item = itemList.get(position); arbitraryCellSelector.getCell(item).bind(holder, item); } @Override public final int getItemCount() { return itemList.size(); } } public abstract class ArbitraryCellHolder<T> extends RecyclerView.ViewHolder { public ArbitraryCellHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public abstract void bind(T item); } public final class ArbitraryCellSelector { private List<Cell> cellList = new ArrayList<>(); public void addCell(Cell cell) { cellList.add(cell); } public void removeCell(Cell cell) { cellList.remove(cell); } public Cell getCell(Object item) { for (Cell cell : cellList) { if (cell.is(item)) { return cell; } } throw new NoSuchRecyclerRowException(); } public Cell getCell(int viewType) { for (Cell cell : cellList) { if (cell.type() == viewType) { return cell; } } throw new NoSuchRecyclerRowException(); } public interface Cell { boolean is(Object item); int type(); RecyclerView.ViewHolder holder(ViewGroup parent); void bind(RecyclerView.ViewHolder holder, Object item); } } public class AdArbitraryCell implements ArbitraryCellSelector.Cell { private PublishSubject<AdVo> adPublishSubject = PublishSubject.create(); @Override public boolean is(Object item) { return item instanceof AdVo; } @Override public int type() { return R.layout.cell_ad; } @Override public RecyclerView.ViewHolder holder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.cell_ad, parent, false); return new AdViewHolder(view); } @Override public void bind(RecyclerView.ViewHolder holder, Object item) { try { AdViewHolder adViewHolder = (AdViewHolder) holder; AdVo ad = (AdVo) item; adViewHolder.bind(ad); } catch (ClassCastException e) { L.printStackTrace(e); } } public Observable<AdVo> asAdObservable() { return adPublishSubject; } protected class AdViewHolder extends ArbitraryCellHolder<AdVo> { @BindView(R.id.ad_text_view) protected TextView adTextView; public AdViewHolder(View itemView) { super(itemView); } @Override public void bind(AdVo item) { adTextView.setText(item.getTitle()); itemView.setOnClickListener(view -> adPublishSubject.onNext(item)); } } } // Other arbitrary cells...
Source: https://habr.com/ru/post/320242/
All Articles