// Header' Footer' public static final int TYPE_HEADER = 7898; public static final int TYPE_FOOTER = 7899; // private List<View> headers = new ArrayList<>(); private List<View> footers = new ArrayList<>(); @Override public VH onCreateViewHolder(ViewGroup viewGroup, int type) { // , ViewHolder if (type != TYPE_HEADER && type != TYPE_FOOTER) { return (VH) onCreteItemViewHolder(viewGroup, type); // header footer } else { // FrameLayout , , View FrameLayout frameLayout = new FrameLayout(viewGroup.getContext()); frameLayout.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); // ViewHolder header' footer'. , FrameLayout return (VH) new HeaderFooterViewHolder(frameLayout); } } @Override final public void onBindViewHolder(final RecyclerView.ViewHolder vh, int position) { // header/footer, if (isHeader(position)) { View v = headers.get(position); prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else if (isFooter(position)) { View v = footers.get(position - getRealItemCount() - getHeadersCount()); prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else { onBindItemViewHolder((VH) vh, position - headers.size(), getItemType(position)); } } @Override final public int getItemViewType(int position) { // if (isHeader(position)) { return TYPE_HEADER; } else if (isFooter(position)) { return TYPE_FOOTER; } int type = getItemType(position); if (type == TYPE_HEADER || type == TYPE_FOOTER) { throw new IllegalArgumentException("Item type cannot equal " + TYPE_HEADER + " or " + TYPE_FOOTER); } return type; }
// private List<T> items = new ArrayList<>(); // - header' footer' public int getRealItemCount() { return items.size(); } // public T getItem(int position) { return items.get(position); } // public void add(int position, T item) { // items.add(position, item); // notifyItemInserted(position); // ViewHolder , int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; notifyItemRangeChanged(positionStart, itemCount); } // public void add(T item) { // items.add(item); // notifyItemInserted(items.size() - 1 + getHeadersCount()); } // List , List, . , , public void addAll(List<? extends T> items) { final int size = this.items.size(); // this.items.addAll(items); // notifyItemRangeInserted(size + getHeadersCount(), items.size()); } // public void set(int position, T item) { // items.set(position, item); // ViewHolder , int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; // notifyItemRangeChanged(positionStart, itemCount); } // public void removeChild(int position) { // items.remove(position); // notifyItemRemoved(position + getHeadersCount()); // ViewHolder , int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; notifyItemRangeChanged(positionStart, itemCount); } // Header' Footer' public void clear() { final int size = items.size(); // items.clear(); // notifyItemRangeRemoved(getHeadersCount(), size); } // public void moveChildTo(int fromPosition, int toPosition) { // if (toPosition != -1 && toPosition < items.size()) { // ... final T item = items.remove(fromPosition); // items.add(toPosition, item); // notifyItemMoved(getHeadersCount() + fromPosition, getHeadersCount() + toPosition); // ViewHolder , int positionStart = fromPosition < toPosition ? fromPosition : toPosition; int itemCount = Math.abs(fromPosition - toPosition) + 1; notifyItemRangeChanged(positionStart + getHeadersCount(), itemCount); } } // public int indexOf(T object) { return items.indexOf(object); }
public abstract class RecyclerBindableAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { public static final int TYPE_HEADER = 7898; public static final int TYPE_FOOTER = 7899; private List<View> headers = new ArrayList<>(); private List<View> footers = new ArrayList<>(); private List<T> items = new ArrayList<>(); private RecyclerView.LayoutManager manager; private LayoutInflater inflater; private GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return getGridSpan(position); } }; public int getRealItemCount() { return items.size(); } public T getItem(int position) { return items.get(position); } public void add(int position, T item) { items.add(position, item); notifyItemInserted(position); int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; notifyItemRangeChanged(positionStart, itemCount); } public void add(T item) { items.add(item); notifyItemInserted(items.size() - 1 + getHeadersCount()); } public void addAll(List<? extends T> items) { final int size = this.items.size(); this.items.addAll(items); notifyItemRangeInserted(size + getHeadersCount(), items.size()); } public void set(int position, T item) { items.set(position, item); int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; notifyItemRangeChanged(positionStart, itemCount); } public void removeChild(int position) { items.remove(position); notifyItemRemoved(position + getHeadersCount()); int positionStart = position + getHeadersCount(); int itemCount = items.size() - position; notifyItemRangeChanged(positionStart, itemCount); } public void clear() { final int size = items.size(); items.clear(); notifyItemRangeRemoved(getHeadersCount(), size); } public void moveChildTo(int fromPosition, int toPosition) { if (toPosition != -1 && toPosition < items.size()) { final T item = items.remove(fromPosition); items.add(toPosition, item); notifyItemMoved(getHeadersCount() + fromPosition, getHeadersCount() + toPosition); int positionStart = fromPosition < toPosition ? fromPosition : toPosition; int itemCount = Math.abs(fromPosition - toPosition) + 1; notifyItemRangeChanged(positionStart + getHeadersCount(), itemCount); } } //@TODO need test public int indexOf(T object) { return items.indexOf(object); } @Override public VH onCreateViewHolder(ViewGroup viewGroup, int type) { //if our position is one of our items (this comes from getItemViewType(int position) below) if (type != TYPE_HEADER && type != TYPE_FOOTER) { return (VH) onCreteItemViewHolder(viewGroup, type); //else we have a header/footer } else { //create a new framelayout, or inflate from a resource FrameLayout frameLayout = new FrameLayout(viewGroup.getContext()); //make sure it fills the space frameLayout.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return (VH) new HeaderFooterViewHolder(frameLayout); } } @Override final public void onBindViewHolder(final RecyclerView.ViewHolder vh, int position) { //check what type of view our position is if (isHeader(position)) { View v = headers.get(position); //add our view to a header view and display it prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else if (isFooter(position)) { View v = footers.get(position - getRealItemCount() - getHeadersCount()); //add our view to a footer view and display it prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else { //it's one of our items, display as required onBindItemViewHolder((VH) vh, position - headers.size(), getItemType(position)); } } private void prepareHeaderFooter(HeaderFooterViewHolder vh, View view) { //if it's a staggered grid, span the whole layout if (manager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); layoutParams.setFullSpan(true); vh.itemView.setLayoutParams(layoutParams); } //if the view already belongs to another layout, remove it if (view.getParent() != null) { ((ViewGroup) view.getParent()).removeView(view); } //empty out our FrameLayout and replace with our header/footer ((ViewGroup) vh.itemView).removeAllViews(); ((ViewGroup) vh.itemView).addView(view); } private boolean isHeader(int position) { return (position < headers.size()); } private boolean isFooter(int position) { return footers.size() > 0 && (position >= getHeadersCount() + getRealItemCount()); } protected VH onCreteItemViewHolder(ViewGroup parent, int type) { return viewHolder(inflater.inflate(layoutId(type), parent, false), type); } @Override public int getItemCount() { return headers.size() + getRealItemCount() + footers.size(); } @Override final public int getItemViewType(int position) { //check what type our position is, based on the assumption that the order is headers > items > footers if (isHeader(position)) { return TYPE_HEADER; } else if (isFooter(position)) { return TYPE_FOOTER; } int type = getItemType(position); if (type == TYPE_HEADER || type == TYPE_FOOTER) { throw new IllegalArgumentException("Item type cannot equal " + TYPE_HEADER + " or " + TYPE_FOOTER); } return type; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); if (manager == null) { setManager(recyclerView.getLayoutManager()); } if (inflater == null) { this.inflater = LayoutInflater.from(recyclerView.getContext()); } } private void setManager(RecyclerView.LayoutManager manager) { this.manager = manager; if (this.manager instanceof GridLayoutManager) { ((GridLayoutManager) this.manager).setSpanSizeLookup(spanSizeLookup); } else if (this.manager instanceof StaggeredGridLayoutManager) { ((StaggeredGridLayoutManager) this.manager).setGapStrategy( StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS); } } protected int getGridSpan(int position) { if (isHeader(position) || isFooter(position)) { return getMaxGridSpan(); } position -= headers.size(); if (getItem(position) instanceof SpanItemInterface) { return ((SpanItemInterface) getItem(position)).getGridSpan(); } return 1; } protected int getMaxGridSpan() { if (manager instanceof GridLayoutManager) { return ((GridLayoutManager) manager).getSpanCount(); } else if (manager instanceof StaggeredGridLayoutManager) { return ((StaggeredGridLayoutManager) manager).getSpanCount(); } return 1; } //add a header to the adapter public void addHeader(View header) { if (!headers.contains(header)) { headers.add(header); //animate notifyItemInserted(headers.size() - 1); } } //@TODO need test public void removeHeader(View header) { if (headers.contains(header)) { //animate notifyItemRemoved(headers.indexOf(header)); headers.remove(header); } } //add a footer to the adapter public void addFooter(View footer) { if (!footers.contains(footer)) { footers.add(footer); //animate notifyItemInserted(headers.size() + getItemCount() + footers.size() - 1); } } //@TODO need test public void removeFooter(View footer) { if (footers.contains(footer)) { //animate notifyItemRemoved(headers.size() + getItemCount() + footers.indexOf(footer)); footers.remove(footer); } } public int getHeadersCount() { return headers.size(); } protected View getHeader(int location) { return headers.get(location); } public int getFootersCount() { return footers.size(); } protected View getFooter(int location) { return footers.get(location); } protected int getItemType(int position) { return 0; } abstract protected void onBindItemViewHolder(VH viewHolder, int position, int type); protected abstract VH viewHolder(View view, int type); protected abstract @LayoutRes int layoutId(int type); public interface SpanItemInterface { int getGridSpan(); } //our header/footer RecyclerView.ViewHolder is just a FrameLayout public static class HeaderFooterViewHolder extends RecyclerView.ViewHolder { public HeaderFooterViewHolder(View itemView) { super(itemView); } } }
public class LinearExampleAdapter extends RecyclerBindableAdapter<Integer, LinearViewHolder> { private LinearViewHolder.ActionListener actionListener; // layout id @Override protected int layoutId(int type) { return R.layout.linear_example_item; } // ViewHolder @Override protected LinearViewHolder viewHolder(View view, int type) { return new LinearViewHolder(view); } // @Override protected void onBindItemViewHolder(LinearViewHolder viewHolder, final int position, int type) { viewHolder.bindView(getItem(position), position, actionListener); } // public void setActionListener(LinearViewHolder.ActionListener actionListener) { this.actionListener = actionListener; } }
public class LinearViewHolder extends RecyclerView.ViewHolder { @Bind(R.id.linear_example_item_text) TextView text; private int position; private ActionListener actionListener; public LinearViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public void bindView(Integer item, int position, ActionListener listener) { actionListener = listener; this.position = position; text.setText(String.valueOf(item)); } @OnClick(R.id.linear_example_item_move_to_top) protected void OnMoveToTopClick() { if (actionListener != null) { actionListener.onMoveToTop(position); } } @OnClick(R.id.linear_example_item_remove) protected void OnRemoveClick() { if (actionListener != null) { actionListener.OnRemove(position); } } @OnClick(R.id.linear_example_item_up) protected void OnUpClick() { if (actionListener != null) { actionListener.OnUp(position); } } @OnClick(R.id.linear_example_item_down) protected void OnDownClick() { if (actionListener != null) { actionListener.OnDown(position); } } public interface ActionListener { void onMoveToTop(int position); void OnRemove(int position); void OnUp(int position); void OnDown(int position); } }
// private List<T> originalValues; private List<T> objects; protected FilterBindableAdapter() { objects = new ArrayList<T>(); originalValues = new ArrayList<T>(); } // , , @Override public void addAll(List<? extends T> data) { // if (objects.containsAll(data)) { return; } // objects.clear(); objects.addAll(data); // originalValues.clear(); originalValues.addAll(data); // notifyItemRangeInserted(getHeadersCount(), data.size()); } //
// public Filter getFilter() { if (filter == null) { filter = new ArrayFilter(); } return filter; } // public interface OnFilterObjectCallback { void handle(int countFilterObject); } // private class ArrayFilter extends Filter { // @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); // prefix , if (prefix == null || prefix.length() == 0) { ArrayList<T> list; synchronized (lock) { list = new ArrayList<T>(originalValues); } results.values = list; results.count = list.size(); // } else { // String prefixString = prefix.toString().toLowerCase(); ArrayList<T> values; synchronized (lock) { values = new ArrayList<T>(originalValues); } final int count = values.size(); final ArrayList<T> newValues = new ArrayList<T>(); // for (int i = 0; i < count; i++) { final T value = values.get(i); final String valueText = itemToString(value).toLowerCase(); // if (valueText.startsWith(prefixString)) { newValues.add(value); // , } else { final String[] words = valueText.split(" "); // , for (String word : words) { if (word.startsWith(prefixString)) { newValues.add(value); break; } } } } results.values = newValues; results.count = newValues.size(); } return results; } // @Override protected void publishResults(CharSequence constraint, FilterResults results) { objects = (List<T>) results.values; // callback if (onFilterObjectCallback != null) { onFilterObjectCallback.handle(results.count); } notifyDataSetChanged(); } }
@Override protected String itemToString(String item) { return item; }
public abstract class FilterBindableAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerBindableAdapter<T, VH> { private final Object lock = new Object(); private List<T> originalValues; private List<T> objects; private ArrayFilter filter; private OnFilterObjectCallback onFilterObjectCallback; protected FilterBindableAdapter() { objects = new ArrayList<T>(); originalValues = new ArrayList<T>(); } @Override public void addAll(List<? extends T> data) { if (objects.containsAll(data)) { return; } objects.clear(); objects.addAll(data); originalValues.clear(); originalValues.addAll(data); notifyItemRangeInserted(getHeadersCount(), data.size()); } //@TODO need test public void addShowed(List<? extends T> data) { objects.clear(); objects.addAll(data); notifyDataSetChanged(); } //@TODO need test @Override public void removeChild(int position) { objects.remove(position); originalValues.remove(position); objects.remove(position); notifyItemRemoved(position + getHeadersCount()); int positionStart = position + getHeadersCount(); int itemCount = objects.size() - position; notifyItemRangeChanged(positionStart, itemCount); } //@TODO need test public void setOnFilterObjectCallback(OnFilterObjectCallback objectCallback) { onFilterObjectCallback = objectCallback; } @Override public T getItem(int position) { return objects.get(position); } @Override public int getRealItemCount() { return objects.size(); } @Override public long getItemId(int position) { return position; } protected abstract String itemToString(T item); public Filter getFilter() { if (filter == null) { filter = new ArrayFilter(); } return filter; } public interface OnFilterObjectCallback { void handle(int countFilterObject); } private class ArrayFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (originalValues == null) { synchronized (lock) { originalValues = new ArrayList<T>(objects); } } if (prefix == null || prefix.length() == 0) { ArrayList<T> list; synchronized (lock) { list = new ArrayList<T>(originalValues); } results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList<T> values; synchronized (lock) { values = new ArrayList<T>(originalValues); } final int count = values.size(); final ArrayList<T> newValues = new ArrayList<T>(); for (int i = 0; i < count; i++) { final T value = values.get(i); final String valueText = itemToString(value).toLowerCase(); // First match against the whole, non-splitted value if (valueText.startsWith(prefixString)) { newValues.add(value); } else { final String[] words = valueText.split(" "); // Start at index 0, in case valueText starts with space(s) for (String word : words) { if (word.startsWith(prefixString)) { newValues.add(value); break; } } } } results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked objects = (List<T>) results.values; if (onFilterObjectCallback != null) { onFilterObjectCallback.handle(results.count); } notifyDataSetChanged(); } } }
@Override public void addHeader(View header) { if (getHeadersCount() == 0) { super.addHeader(header); } else { removeHeader(getHeader(0)); super.addHeader(header); } } @Override public void addFooter(View footer) { if (getFootersCount() == 0) { super.addFooter(footer); } else { removeFooter(getFooter(0)); super.addFooter(footer); } }
public class ParallaxContainer extends FrameLayout { private final boolean isParallax; private final boolean isFooter; private int offset; public ParallaxContainer(Context context, boolean shouldClick, boolean isFooter) { super(context); isParallax = shouldClick; this.isFooter = isFooter; } @Override protected void dispatchDraw(@NonNull Canvas canvas) { if (isParallax) { int top = isFooter ? -offset : 0; int bottom = isFooter ? getBottom() : getBottom() + offset; Rect rect = new Rect(getLeft(), top, getRight(), bottom); canvas.clipRect(rect); } super.dispatchDraw(canvas); } public void setClipY(int offset) { this.offset = offset; invalidate(); } }
// setter' private boolean isParallaxHeader = true; private boolean isParallaxFooter = true; public void setParallaxHeader(boolean isParallaxHeader) { this.isParallaxHeader = isParallaxHeader; } public void setParallaxFooter(boolean isParallaxFooter) { this.isParallaxFooter = isParallaxFooter; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); // ScrollListener RecyclerView recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // header if (header != null && isParallaxHeader) { translateView(recyclerView.computeVerticalScrollOffset(), header, false); } // footer if (footer != null && isParallaxFooter) { int range = recyclerView.computeVerticalScrollRange(); int extend = recyclerView.computeVerticalScrollExtent(); int offset = recyclerView.computeVerticalScrollOffset(); translateView(range - (extend + offset), footer, true); } } }); } // private void translateView(float of, ParallaxContainer view, boolean isFooter) { float ofCalculated = of * SCROLL_MULTIPLIER; // footer ofCalculated = isFooter ? -ofCalculated : ofCalculated; // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { view.setTranslationY(ofCalculated); } else { TranslateAnimation anim = new TranslateAnimation(0, 0, ofCalculated, ofCalculated); anim.setFillAfter(true); anim.setDuration(0); view.startAnimation(anim); } // view.setClipY(Math.round(ofCalculated)); // callback, ( / ActionBar ) if (parallaxScroll != null && !isFooter) { float left = Math.min(1, ((ofCalculated) / (view.getHeight() * SCROLL_MULTIPLIER))); parallaxScroll.onParallaxScroll(left, of, view); } }
public abstract class ParallaxBindableAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerBindableAdapter<T, VH> { private static final float SCROLL_MULTIPLIER = 0.5f; private ParallaxContainer header; private ParallaxContainer footer; private OnParallaxScroll parallaxScroll; private boolean isParallaxHeader = true; private boolean isParallaxFooter = true; //parallax adapter may have only one header @Override public void addHeader(View header) { if (getHeadersCount() == 0) { super.addHeader(header); } else { removeHeader(getHeader(0)); super.addHeader(header); } } //parallax adapter may have only one header @Override public void addFooter(View footer) { if (getFootersCount() == 0) { super.addFooter(footer); } else { removeFooter(getFooter(0)); super.addFooter(footer); } } private void translateView(float of, ParallaxContainer view, boolean isFooter) { float ofCalculated = of * SCROLL_MULTIPLIER; ofCalculated = isFooter ? -ofCalculated : ofCalculated; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { view.setTranslationY(ofCalculated); } else { TranslateAnimation anim = new TranslateAnimation(0, 0, ofCalculated, ofCalculated); anim.setFillAfter(true); anim.setDuration(0); view.startAnimation(anim); } view.setClipY(Math.round(ofCalculated)); if (parallaxScroll != null && !isFooter) { float left = Math.min(1, ((ofCalculated) / (view.getHeight() * SCROLL_MULTIPLIER))); parallaxScroll.onParallaxScroll(left, of, view); } } @Override public VH onCreateViewHolder(ViewGroup viewGroup, int type) { //if our position is one of our items (this comes from getItemViewType(int position) below) if (type != TYPE_HEADER && type != TYPE_FOOTER) { return (VH) onCreteItemViewHolder(viewGroup, type); //else if we have a header } else if (type == TYPE_HEADER) { //create a new ParallaxContainer header = new ParallaxContainer(viewGroup.getContext(), isParallaxHeader, false); //make sure it fills the space header.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return (VH) new HeaderFooterViewHolder(header); //else we have a footer } else { //create a new ParallaxContainer footer = new ParallaxContainer(viewGroup.getContext(), isParallaxFooter, true); //make sure it fills the space footer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return (VH) new HeaderFooterViewHolder(footer); } } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (header != null && isParallaxHeader) { translateView(recyclerView.computeVerticalScrollOffset(), header, false); } if (footer != null && isParallaxFooter) { int range = recyclerView.computeVerticalScrollRange(); int extend = recyclerView.computeVerticalScrollExtent(); int offset = recyclerView.computeVerticalScrollOffset(); translateView(range - (extend + offset), footer, true); } } }); } public void setParallaxHeader(boolean isParallaxHeader) { this.isParallaxHeader = isParallaxHeader; } public void setParallaxFooter(boolean isParallaxFooter) { this.isParallaxFooter = isParallaxFooter; } public void setOnParallaxScroll(OnParallaxScroll parallaxScroll) { this.parallaxScroll = parallaxScroll; this.parallaxScroll.onParallaxScroll(0, 0, header); } public interface OnParallaxScroll { /** * Event triggered when the parallax is being scrolled. * * @param percentage * @param offset * @param parallax */ void onParallaxScroll(float percentage, float offset, View parallax); } }
public abstract class BindableViewHolder<T> extends RecyclerView.ViewHolder { public BindableViewHolder(View itemView) { super(itemView); } // , OnItemClickListener public void bindView(final int position, final T item, final ActionListener actionListener) { if (actionListener != null) { itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { actionListener.OnItemClickListener(position, item); } }); } } // public interface ActionListener { void OnItemClickListener(int position, Object Item); } }
// final, , , . , VH BindableViewHolder public final class SimpleBindableAdapter<T, VH extends BindableViewHolder> extends RecyclerBindableAdapter<T, VH> { // layout id @LayoutRes private final int layoutId; // ViewHolder , ViewHolder Class<VH> vhClass; // BindableViewHolder.ActionListener actionListener; public SimpleBindableAdapter(@LayoutRes int layoutId, Class<VH> vhClass) { this.layoutId = layoutId; this.vhClass = vhClass; } @Override protected void onBindItemViewHolder(BindableViewHolder viewHolder, int position, int type) { // ViewHolder, BindableViewHolder viewHolder.bindView(position, getItem(position), actionListener); } @Override protected VH viewHolder(View view, int type) { // Java Reflection ViewHolder try { return (VH) vhClass.getConstructor(View.class).newInstance(view); } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } catch (NoSuchMethodException e) { e.printStackTrace(); return null; } catch (InvocationTargetException e) { e.printStackTrace(); return null; } } @Override protected int layoutId(int type) { return layoutId; } public void setActionListener(BindableViewHolder.ActionListener actionListener) { this.actionListener = actionListener; } }
private SimpleBindableAdapter<Integer, SimpleViewHolder> simpleExampleAdapter; @Override protected void onCreate(Bundle savedInstanceState) { ............................................................................................. simpleExampleAdapter = new SimpleBindableAdapter<>(R.layout.simple_example_item, SimpleViewHolder.class); simpleExampleAdapter.setActionListener(new SimpleViewHolder.SimpleActionListener() { ............................................................................................. } simpleExampleRecycler.setAdapter(simpleExampleAdapter); .............................................................................................. }
public class SimpleViewHolder extends BindableViewHolder<Integer> { @Bind(R.id.simple_example_item_tittle) TextView tittle; private int position; private SimpleActionListener simpleActionListener; public SimpleViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } @Override public void bindView(int position, Integer item, ActionListener actionListener) { super.bindView(position, item, actionListener); this.position = position; simpleActionListener = (SimpleActionListener) actionListener; tittle.setText(String.valueOf(item)); } @OnClick(R.id.simple_example_item_move_to_top) protected void OnMoveToTopClick() { if (simpleActionListener != null) { simpleActionListener.onMoveToTop(position); } } @OnClick(R.id.simple_example_item_remove) protected void OnRemoveClick() { if (simpleActionListener != null) { simpleActionListener.OnRemove(position); } } @OnClick(R.id.simple_example_item_up) protected void OnUpClick() { if (simpleActionListener != null) { simpleActionListener.OnUp(position); } } @OnClick(R.id.simple_example_item_down) protected void OnDownClick() { if (simpleActionListener != null) { simpleActionListener.OnDown(position); } } public interface SimpleActionListener extends ActionListener { void onMoveToTop(int position); void OnRemove(int position); void OnUp(int position); void OnDown(int position); } }
Source: https://habr.com/ru/post/269057/
All Articles