package de.westnordost.streetcomplete.view; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import de.westnordost.streetcomplete.R; public class ImageSelectAdapter extends RecyclerView.Adapter<ImageSelectAdapter.ViewHolder> { private ArrayList<ImageSelectAdapter.Item> items; private Set<Integer> selectedIndices; private int maxSelectableIndices; private int cellLayoutId = R.layout.labeled_image_select_cell; public interface OnItemSelectionListener { void onIndexSelected(int index); void onIndexDeselected(int index); } private ImageSelectAdapter.OnItemSelectionListener onItemSelectionListener; public ImageSelectAdapter() { selectedIndices = new HashSet<>(); this.maxSelectableIndices = -1; } public ImageSelectAdapter(int maxSelectableIndices) { selectedIndices = new HashSet<>(); this.maxSelectableIndices = maxSelectableIndices; } public void setOnItemSelectionListener( ImageSelectAdapter.OnItemSelectionListener onItemSelectionListener) { this.onItemSelectionListener = onItemSelectionListener; } public void setCellLayout(int cellLayoutId) { this.cellLayoutId = cellLayoutId; } public ArrayList<Integer> getSelectedIndices() { return new ArrayList<>(selectedIndices); } public void selectIndices(List<Integer> indices) { for(Integer index : indices) { selectIndex(index); } } public void setItems(List<ImageSelectAdapter.Item> items) { this.items = new ArrayList<>(items); notifyDataSetChanged(); } public void addItems(Collection<ImageSelectAdapter.Item> items) { int len = this.items.size(); this.items.addAll(items); notifyItemRangeInserted(len, items.size()); } @Override public ImageSelectAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()). inflate(cellLayoutId, parent, false); return new ImageSelectAdapter.ViewHolder(view); } public boolean isIndexSelected(int index) { return selectedIndices.contains(index); } public void selectIndex(int index) { checkIndexRange(index); // special case: toggle-behavior if only one index can be selected if(maxSelectableIndices == 1 && selectedIndices.size() == 1) { deselectIndex(selectedIndices.iterator().next()); } else if(maxSelectableIndices > -1 && maxSelectableIndices <= selectedIndices.size()) { return; } selectedIndices.add(index); notifyItemChanged(index); if(onItemSelectionListener != null) { onItemSelectionListener.onIndexSelected(index); } } public void deselectIndex(int index) { checkIndexRange(index); selectedIndices.remove(index); notifyItemChanged(index); if(onItemSelectionListener != null) { onItemSelectionListener.onIndexDeselected(index); } } public void toggleIndex(int index) { checkIndexRange(index); if(!isIndexSelected(index)) { selectIndex(index); } else { deselectIndex(index); } } private void checkIndexRange(int index) { if(index < 0 || index >= items.size()) throw new ArrayIndexOutOfBoundsException(index); } @Override public void onBindViewHolder(ImageSelectAdapter.ViewHolder holder, int position) { ImageSelectAdapter.Item item = items.get(position); holder.imageView.setImageResource(item.drawableId); holder.itemView.setSelected(isIndexSelected(position)); if(item.titleId > -1) holder.textView.setText(item.titleId); else holder.textView.setText(""); } @Override public int getItemCount() { if(items == null) return 0; return items.size(); } class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { ImageView imageView; TextView textView; public ViewHolder(View v) { super(v); imageView = (ImageView) itemView.findViewById(R.id.imageView); imageView.setOnClickListener(this); textView = (TextView) itemView.findViewById(R.id.textView); } @Override public void onClick(View v) { toggleIndex(getAdapterPosition()); } } public static class Item { public final int titleId; public final int drawableId; public Item(int drawableId, int titleId) { this.drawableId = drawableId; this.titleId = titleId; } } }