Reputation: 41
I am making an app with personalisation feature where user can select his preference and based on that app will show data. on click of item it should be selected (making item border highlighted) and on re-click it should be unselected also there should be multiselection in recyclerview.here is the screen shot of my app's personalisation screen
Upvotes: 2
Views: 11681
Reputation: 1597
isSelected (boolean)
on Object
that working with recyclerview
.Adapter
class, at the onBindViewHolder
method: use setOnClickListener
for ImageView
that show avatar. When user click on, change isSelected
for object and set background for imageView
with isSelected
is true and false.Upvotes: 2
Reputation: 628
Adding to sonnv1368's answer :
Try this :
Create a boolean in your model class object to keep track of selection of imageview : say boolean isSelected;
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
Object item = objectList.get(position);
holder.imageView.setSelected(item.getSelected());
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView;
public ViewHolder(View view) {
//initialization code here
imageView.setOnClickListener(this);
}
@Override
public void onClick( View view ) {
Object object = objectList.get(getAdapterPosition());
object.isSelected() ? object.setSelected(false) : object.setSelected(true);
notifyItemChanged(getAdapterPosition());
}
}
Upvotes: 4
Reputation: 1493
Use this to select multiple rows in recyclerview and delete with actionmode.
SelectableAdapter.class
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
@SuppressWarnings("unused")
private static final String TAG = SelectableAdapter.class.getSimpleName();
private SparseBooleanArray selectedItems;
public SelectableAdapter() {
selectedItems = new SparseBooleanArray();
}
/**
* Indicates if the item at position position is selected
* @param position Position of the item to check
* @return true if the item is selected, false otherwise
*/
public boolean isSelected(int position) {
return getSelectedItems().contains(position);
}
/**
* Toggle the selection status of the item at a given position
* @param position Position of the item to toggle the selection status for
*/
public void toggleSelection(int position) {
if (selectedItems.get(position, false)) {
selectedItems.delete(position);
} else {
selectedItems.put(position, true);
}
notifyItemChanged(position);
}
/**
* Clear the selection status for all items
*/
public void clearSelection() {
List<Integer> selection = getSelectedItems();
selectedItems.clear();
for (Integer i : selection) {
notifyItemChanged(i);
}
}
/**
* Count the selected items
* @return Selected items count
*/
public int getSelectedItemCount() {
return selectedItems.size();
}
/**
* Indicates the list of selected items
* @return List of selected items ids
*/
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); ++i) {
items.add(selectedItems.keyAt(i));
}
return items;
}
}
Item.class
public class Item {
private String title;
public Item(String title){
this.title=title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Adapter.class
public class Adapter extends SelectableAdapter<Adapter.ViewHolder> {
@SuppressWarnings("unused")
private static final String TAG = Adapter.class.getSimpleName();
private static final int ITEM_COUNT = 50;
private List<Item> items;
private ViewHolder.ClickListener clickListener;
public Adapter(ViewHolder.ClickListener clickListener) {
super();
this.clickListener = clickListener;
items = new ArrayList<>();
for (int i = 0; i < ITEM_COUNT; ++i) {
items.add(new Item("Item " + i));
}
}
public void removeItem(int position) {
items.remove(position);
notifyItemRemoved(position);
}
public void removeItems(List<Integer> positions) {
// Reverse-sort the list
Collections.sort(positions, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return rhs - lhs;
}
});
// Split the list in ranges
while (!positions.isEmpty()) {
if (positions.size() == 1) {
removeItem(positions.get(0));
positions.remove(0);
} else {
int count = 1;
while (positions.size() > count && positions.get(count).equals(positions.get(count - 1) - 1)) {
++count;
}
if (count == 1) {
removeItem(positions.get(0));
} else {
removeRange(positions.get(count - 1), count);
}
for (int i = 0; i < count; ++i) {
positions.remove(0);
}
}
}
}
private void removeRange(int positionStart, int itemCount) {
for (int i = 0; i < itemCount; ++i) {
items.remove(positionStart);
}
notifyItemRangeRemoved(positionStart, itemCount);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_card, parent, false);
return new ViewHolder(v, clickListener);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Item item = items.get(position);
holder.title.setText(item.getTitle());
// Highlight the item if it's selected
holder.selectedOverlay.setVisibility(isSelected(position) ? View.VISIBLE : View.INVISIBLE);
}
@Override
public int getItemCount() {
return items.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnLongClickListener {
@SuppressWarnings("unused")
private static final String TAG = ViewHolder.class.getSimpleName();
TextView title;
TextView subtitle;
View selectedOverlay;
private ClickListener listener;
public ViewHolder(View itemView, ClickListener listener) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.textView);
selectedOverlay = (View)itemView.findViewById(R.id.selectedOverlay);
this.listener = listener;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClicked(getLayoutPosition());
}
}
@Override
public boolean onLongClick(View v) {
if (listener != null) {
return listener.onItemLongClicked(getLayoutPosition());
}
return false;
}
public interface ClickListener {
void onItemClicked(int position);
boolean onItemLongClicked(int position);
}
}
}
MainActivity.class
public class MainActivity extends AppCompatActivity implements Adapter.ViewHolder.ClickListener {
@SuppressWarnings("unused")
private static final String TAG = MainActivity.class.getSimpleName();
private Adapter adapter;
private ActionModeCallback actionModeCallback = new ActionModeCallback();
private ActionMode actionMode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new Adapter(this);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new GridLayoutManager(this,3));
}
@Override
public void onItemClicked(int position) {
if (actionMode != null) {
toggleSelection(position);
} else {
//adapter.removeItem(position);
}
}
@Override
public boolean onItemLongClicked(int position) {
if (actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback);
}
toggleSelection(position);
return true;
}
/**
* Toggle the selection state of an item.
*
* If the item was the last one in the selection and is unselected, the selection is stopped.
* Note that the selection must already be started (actionMode must not be null).
*
* @param position Position of the item to toggle the selection state
*/
private void toggleSelection(int position) {
adapter.toggleSelection(position);
int count = adapter.getSelectedItemCount();
if (count == 0) {
actionMode.finish();
} else {
actionMode.setTitle(String.valueOf(count));
actionMode.invalidate();
}
}
private class ActionModeCallback implements ActionMode.Callback {
@SuppressWarnings("unused")
private final String TAG = ActionModeCallback.class.getSimpleName();
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate (R.menu.toolbar_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
adapter.removeItems(adapter.getSelectedItems());
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
adapter.clearSelection();
actionMode = null;
}
}
}
item_card.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:foreground="?android:attr/selectableItemBackground"
app:cardUseCompatPadding="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/textView"
android:padding="7dp"
android:text="sample"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
android:id="@+id/selectedOverlay"
android:background="@color/transparent"/>
</android.support.v7.widget.CardView>
Upvotes: 3
Reputation: 13555
This is bit similar what you looking for,try to use DragSelectRecyclerView it will work for you,and for border highlight create one selector for that.
<com.afollestad.dragselectrecyclerview.DragSelectRecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
and you can also use that way
http://www.grokkingandroid.com/statelistdrawables-for-recyclerview-selection/
http://bignerdranch.github.io/recyclerview-multiselect/
Upvotes: 0