Android recyclerview-selection Implementation?












5















I'm currently trying to implement the new recyclerview-selection APIs from Android Support Library 28.0.0-alpha1, and am running into some issues. My goal is to have a RecyclerView, with the ability to select multiple rows, show a Contextual Action Bar, and perform actions on them, such as "delete" or "share"



I'll try and furnish enough code to give a good idea of what's going on, but I can always respond with more if necessary.



In my Fragment which contains the RecyclerView I'm concerned with, I am initiating a SelectionTracker, and setting it on my RecyclerView.Adapter, like so:



private void buildRecyclerView() {
sheetsAdapter = new SheetsAdapter(getContext(), this, sheets);
gridManager = new GridLayoutManager(getContext(), getResources().getInteger(R.integer.grid_span_count));

ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getContext(), R.dimen.item_offset);
sheetsRecycler.addItemDecoration(itemDecoration);
sheetsRecycler.setLayoutManager(gridManager);
sheetsRecycler.setAdapter(sheetsAdapter);
sheetsRecycler.setHasFixedSize(true);

SelectionTracker selectionTracker = new SelectionTracker.Builder<>("sheet_selection",
sheetsRecycler,
new StableIdKeyProvider(sheetsRecycler),
new SheetDetailsLookup(sheetsRecycler),
StorageStrategy.createLongStorage())
.withOnContextClickListener(this)
.build();

sheetsAdapter.setSelectionTracker(selectionTracker);
}


This Fragment also implements OnContextClickListener, in order to listen for long-clicks on the items in my RecyclerView:



@Override
public boolean onContextClick(@NonNull MotionEvent e) {
if (actionMode != null) {
return false;
}

// Start the CAB using the ActionMode.Callback defined below
if (getActivity() != null) {
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}

return true;
}


And it should show my CAB, like this:



private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.sheets_cab_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.delete:
Toast.makeText(getContext(), R.string.sheets_delete, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};


My SheetDetailsLookup looks like this:



public class SheetDetailsLookup extends ItemDetailsLookup<Long> {

private RecyclerView recyclerView;

SheetDetailsLookup(RecyclerView recyclerView) {
super();

this.recyclerView = recyclerView;
}

@Nullable
@Override
public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
if (holder instanceof SheetsAdapter.SheetViewHolder) {
return ((SheetsAdapter.SheetViewHolder) holder).getItemDetails();
}
}
return null;
}
}


And in my SheetViewHolder, I update the view to show that it has been selected:



if (selectionTracker.isSelected(sheet.uid)) {
layout.setBackgroundResource(R.color.md_grey_700);
} else {
layout.setBackgroundResource(android.R.color.transparent);
}


As well as:



public SheetItemDetails getItemDetails() {
return new SheetItemDetails(getAdapterPosition(), mSheets.get(getAdapterPosition()).uid);
}


Where SheetItemDetails is simply:



public class SheetItemDetails extends ItemDetailsLookup.ItemDetails<Long> {

private int position;
private Long key;

SheetItemDetails(int position, Long key) {
this.position = position;
this.key = key;
}

@Override
public int getPosition() {
return position;
}

@Nullable
@Override
public Long getSelectionKey() {
return key;
}
}


I've implemented all of the things mentioned in the API specification, but am now running into troubles. My CAB doesn't show up when I select an item... and the app usually crashes. Crashes occur whenever I try to "back out" of selections,and then long-click to start another selection, with this stack trace:



java.lang.IllegalStateException
at android.support.v4.util.Preconditions.checkState(Preconditions.java:130)
at android.support.v4.util.Preconditions.checkState(Preconditions.java:142)
at androidx.recyclerview.selection.GestureSelectionHelper.start(GestureSelectionHelper.java:76)
at androidx.recyclerview.selection.SelectionTracker$Builder$4.run(SelectionTracker.java:742)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:136)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:95)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)


Also, I've now lost the ability to "short-click" on one of my items, to launch a detail view... Which I had working just fine until now.



What have I done wrong?










share|improve this question























  • 1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

    – wangqi060934
    Jun 1 '18 at 3:12











  • I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

    – Jose Ricardo Citerio Alcala
    Jan 2 at 2:17
















5















I'm currently trying to implement the new recyclerview-selection APIs from Android Support Library 28.0.0-alpha1, and am running into some issues. My goal is to have a RecyclerView, with the ability to select multiple rows, show a Contextual Action Bar, and perform actions on them, such as "delete" or "share"



I'll try and furnish enough code to give a good idea of what's going on, but I can always respond with more if necessary.



In my Fragment which contains the RecyclerView I'm concerned with, I am initiating a SelectionTracker, and setting it on my RecyclerView.Adapter, like so:



private void buildRecyclerView() {
sheetsAdapter = new SheetsAdapter(getContext(), this, sheets);
gridManager = new GridLayoutManager(getContext(), getResources().getInteger(R.integer.grid_span_count));

ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getContext(), R.dimen.item_offset);
sheetsRecycler.addItemDecoration(itemDecoration);
sheetsRecycler.setLayoutManager(gridManager);
sheetsRecycler.setAdapter(sheetsAdapter);
sheetsRecycler.setHasFixedSize(true);

SelectionTracker selectionTracker = new SelectionTracker.Builder<>("sheet_selection",
sheetsRecycler,
new StableIdKeyProvider(sheetsRecycler),
new SheetDetailsLookup(sheetsRecycler),
StorageStrategy.createLongStorage())
.withOnContextClickListener(this)
.build();

sheetsAdapter.setSelectionTracker(selectionTracker);
}


This Fragment also implements OnContextClickListener, in order to listen for long-clicks on the items in my RecyclerView:



@Override
public boolean onContextClick(@NonNull MotionEvent e) {
if (actionMode != null) {
return false;
}

// Start the CAB using the ActionMode.Callback defined below
if (getActivity() != null) {
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}

return true;
}


And it should show my CAB, like this:



private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.sheets_cab_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.delete:
Toast.makeText(getContext(), R.string.sheets_delete, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};


My SheetDetailsLookup looks like this:



public class SheetDetailsLookup extends ItemDetailsLookup<Long> {

private RecyclerView recyclerView;

SheetDetailsLookup(RecyclerView recyclerView) {
super();

this.recyclerView = recyclerView;
}

@Nullable
@Override
public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
if (holder instanceof SheetsAdapter.SheetViewHolder) {
return ((SheetsAdapter.SheetViewHolder) holder).getItemDetails();
}
}
return null;
}
}


And in my SheetViewHolder, I update the view to show that it has been selected:



if (selectionTracker.isSelected(sheet.uid)) {
layout.setBackgroundResource(R.color.md_grey_700);
} else {
layout.setBackgroundResource(android.R.color.transparent);
}


As well as:



public SheetItemDetails getItemDetails() {
return new SheetItemDetails(getAdapterPosition(), mSheets.get(getAdapterPosition()).uid);
}


Where SheetItemDetails is simply:



public class SheetItemDetails extends ItemDetailsLookup.ItemDetails<Long> {

private int position;
private Long key;

SheetItemDetails(int position, Long key) {
this.position = position;
this.key = key;
}

@Override
public int getPosition() {
return position;
}

@Nullable
@Override
public Long getSelectionKey() {
return key;
}
}


I've implemented all of the things mentioned in the API specification, but am now running into troubles. My CAB doesn't show up when I select an item... and the app usually crashes. Crashes occur whenever I try to "back out" of selections,and then long-click to start another selection, with this stack trace:



java.lang.IllegalStateException
at android.support.v4.util.Preconditions.checkState(Preconditions.java:130)
at android.support.v4.util.Preconditions.checkState(Preconditions.java:142)
at androidx.recyclerview.selection.GestureSelectionHelper.start(GestureSelectionHelper.java:76)
at androidx.recyclerview.selection.SelectionTracker$Builder$4.run(SelectionTracker.java:742)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:136)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:95)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)


Also, I've now lost the ability to "short-click" on one of my items, to launch a detail view... Which I had working just fine until now.



What have I done wrong?










share|improve this question























  • 1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

    – wangqi060934
    Jun 1 '18 at 3:12











  • I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

    – Jose Ricardo Citerio Alcala
    Jan 2 at 2:17














5












5








5


3






I'm currently trying to implement the new recyclerview-selection APIs from Android Support Library 28.0.0-alpha1, and am running into some issues. My goal is to have a RecyclerView, with the ability to select multiple rows, show a Contextual Action Bar, and perform actions on them, such as "delete" or "share"



I'll try and furnish enough code to give a good idea of what's going on, but I can always respond with more if necessary.



In my Fragment which contains the RecyclerView I'm concerned with, I am initiating a SelectionTracker, and setting it on my RecyclerView.Adapter, like so:



private void buildRecyclerView() {
sheetsAdapter = new SheetsAdapter(getContext(), this, sheets);
gridManager = new GridLayoutManager(getContext(), getResources().getInteger(R.integer.grid_span_count));

ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getContext(), R.dimen.item_offset);
sheetsRecycler.addItemDecoration(itemDecoration);
sheetsRecycler.setLayoutManager(gridManager);
sheetsRecycler.setAdapter(sheetsAdapter);
sheetsRecycler.setHasFixedSize(true);

SelectionTracker selectionTracker = new SelectionTracker.Builder<>("sheet_selection",
sheetsRecycler,
new StableIdKeyProvider(sheetsRecycler),
new SheetDetailsLookup(sheetsRecycler),
StorageStrategy.createLongStorage())
.withOnContextClickListener(this)
.build();

sheetsAdapter.setSelectionTracker(selectionTracker);
}


This Fragment also implements OnContextClickListener, in order to listen for long-clicks on the items in my RecyclerView:



@Override
public boolean onContextClick(@NonNull MotionEvent e) {
if (actionMode != null) {
return false;
}

// Start the CAB using the ActionMode.Callback defined below
if (getActivity() != null) {
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}

return true;
}


And it should show my CAB, like this:



private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.sheets_cab_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.delete:
Toast.makeText(getContext(), R.string.sheets_delete, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};


My SheetDetailsLookup looks like this:



public class SheetDetailsLookup extends ItemDetailsLookup<Long> {

private RecyclerView recyclerView;

SheetDetailsLookup(RecyclerView recyclerView) {
super();

this.recyclerView = recyclerView;
}

@Nullable
@Override
public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
if (holder instanceof SheetsAdapter.SheetViewHolder) {
return ((SheetsAdapter.SheetViewHolder) holder).getItemDetails();
}
}
return null;
}
}


And in my SheetViewHolder, I update the view to show that it has been selected:



if (selectionTracker.isSelected(sheet.uid)) {
layout.setBackgroundResource(R.color.md_grey_700);
} else {
layout.setBackgroundResource(android.R.color.transparent);
}


As well as:



public SheetItemDetails getItemDetails() {
return new SheetItemDetails(getAdapterPosition(), mSheets.get(getAdapterPosition()).uid);
}


Where SheetItemDetails is simply:



public class SheetItemDetails extends ItemDetailsLookup.ItemDetails<Long> {

private int position;
private Long key;

SheetItemDetails(int position, Long key) {
this.position = position;
this.key = key;
}

@Override
public int getPosition() {
return position;
}

@Nullable
@Override
public Long getSelectionKey() {
return key;
}
}


I've implemented all of the things mentioned in the API specification, but am now running into troubles. My CAB doesn't show up when I select an item... and the app usually crashes. Crashes occur whenever I try to "back out" of selections,and then long-click to start another selection, with this stack trace:



java.lang.IllegalStateException
at android.support.v4.util.Preconditions.checkState(Preconditions.java:130)
at android.support.v4.util.Preconditions.checkState(Preconditions.java:142)
at androidx.recyclerview.selection.GestureSelectionHelper.start(GestureSelectionHelper.java:76)
at androidx.recyclerview.selection.SelectionTracker$Builder$4.run(SelectionTracker.java:742)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:136)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:95)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)


Also, I've now lost the ability to "short-click" on one of my items, to launch a detail view... Which I had working just fine until now.



What have I done wrong?










share|improve this question














I'm currently trying to implement the new recyclerview-selection APIs from Android Support Library 28.0.0-alpha1, and am running into some issues. My goal is to have a RecyclerView, with the ability to select multiple rows, show a Contextual Action Bar, and perform actions on them, such as "delete" or "share"



I'll try and furnish enough code to give a good idea of what's going on, but I can always respond with more if necessary.



In my Fragment which contains the RecyclerView I'm concerned with, I am initiating a SelectionTracker, and setting it on my RecyclerView.Adapter, like so:



private void buildRecyclerView() {
sheetsAdapter = new SheetsAdapter(getContext(), this, sheets);
gridManager = new GridLayoutManager(getContext(), getResources().getInteger(R.integer.grid_span_count));

ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getContext(), R.dimen.item_offset);
sheetsRecycler.addItemDecoration(itemDecoration);
sheetsRecycler.setLayoutManager(gridManager);
sheetsRecycler.setAdapter(sheetsAdapter);
sheetsRecycler.setHasFixedSize(true);

SelectionTracker selectionTracker = new SelectionTracker.Builder<>("sheet_selection",
sheetsRecycler,
new StableIdKeyProvider(sheetsRecycler),
new SheetDetailsLookup(sheetsRecycler),
StorageStrategy.createLongStorage())
.withOnContextClickListener(this)
.build();

sheetsAdapter.setSelectionTracker(selectionTracker);
}


This Fragment also implements OnContextClickListener, in order to listen for long-clicks on the items in my RecyclerView:



@Override
public boolean onContextClick(@NonNull MotionEvent e) {
if (actionMode != null) {
return false;
}

// Start the CAB using the ActionMode.Callback defined below
if (getActivity() != null) {
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}

return true;
}


And it should show my CAB, like this:



private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.sheets_cab_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.delete:
Toast.makeText(getContext(), R.string.sheets_delete, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};


My SheetDetailsLookup looks like this:



public class SheetDetailsLookup extends ItemDetailsLookup<Long> {

private RecyclerView recyclerView;

SheetDetailsLookup(RecyclerView recyclerView) {
super();

this.recyclerView = recyclerView;
}

@Nullable
@Override
public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
if (holder instanceof SheetsAdapter.SheetViewHolder) {
return ((SheetsAdapter.SheetViewHolder) holder).getItemDetails();
}
}
return null;
}
}


And in my SheetViewHolder, I update the view to show that it has been selected:



if (selectionTracker.isSelected(sheet.uid)) {
layout.setBackgroundResource(R.color.md_grey_700);
} else {
layout.setBackgroundResource(android.R.color.transparent);
}


As well as:



public SheetItemDetails getItemDetails() {
return new SheetItemDetails(getAdapterPosition(), mSheets.get(getAdapterPosition()).uid);
}


Where SheetItemDetails is simply:



public class SheetItemDetails extends ItemDetailsLookup.ItemDetails<Long> {

private int position;
private Long key;

SheetItemDetails(int position, Long key) {
this.position = position;
this.key = key;
}

@Override
public int getPosition() {
return position;
}

@Nullable
@Override
public Long getSelectionKey() {
return key;
}
}


I've implemented all of the things mentioned in the API specification, but am now running into troubles. My CAB doesn't show up when I select an item... and the app usually crashes. Crashes occur whenever I try to "back out" of selections,and then long-click to start another selection, with this stack trace:



java.lang.IllegalStateException
at android.support.v4.util.Preconditions.checkState(Preconditions.java:130)
at android.support.v4.util.Preconditions.checkState(Preconditions.java:142)
at androidx.recyclerview.selection.GestureSelectionHelper.start(GestureSelectionHelper.java:76)
at androidx.recyclerview.selection.SelectionTracker$Builder$4.run(SelectionTracker.java:742)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:136)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:95)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)


Also, I've now lost the ability to "short-click" on one of my items, to launch a detail view... Which I had working just fine until now.



What have I done wrong?







android android-recyclerview multipleselection android-actionmode






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 28 '18 at 23:27









drinfernoodrinfernoo

2613




2613













  • 1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

    – wangqi060934
    Jun 1 '18 at 3:12











  • I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

    – Jose Ricardo Citerio Alcala
    Jan 2 at 2:17



















  • 1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

    – wangqi060934
    Jun 1 '18 at 3:12











  • I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

    – Jose Ricardo Citerio Alcala
    Jan 2 at 2:17

















1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

– wangqi060934
Jun 1 '18 at 3:12





1. withOnContextClickListener is not for long-click 2.your getItemDetails returns a new instance every time. Can you paste the entire code?

– wangqi060934
Jun 1 '18 at 3:12













I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

– Jose Ricardo Citerio Alcala
Jan 2 at 2:17





I'm facing the short-click trouble too. I'm using Kotlin and ParcelableStorage for the item key and everything is working fine but the simple click listener event. How did you solve this?

– Jose Ricardo Citerio Alcala
Jan 2 at 2:17












4 Answers
4






active

oldest

votes


















4














I recently started looking at this library and got stuck on the same exception. The problem occurs when the SelectionTracker attempts to get an id from your custom RecyclerView.Adapter subclass. To fix the problem, first call setHasStableIds(true) in its constructor. Then override getItemId() to return an id for the given position parameter.






share|improve this answer
























  • This should be the right answer

    – A. Petrov
    Nov 20 '18 at 6:25



















2














New library looks complicated for now, indeed. I would wait the new final version before starting to implement over it. Surely, you can experiment with it, but I suggest you not use it in your app for now.



There's only one nice, new feature: the continuous multi-selection by moving the finger or mouse.



However, I found these examples:




  • https://github.com/Thumar/recyclerview-selection

  • https://github.com/guenodz/recyclerview-selection-demo

  • https://medium.com/@Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825


In the meantime, I strongly suggest to use a library like mine: FlexibleAdapter which comes from more than 3 years of "selection experience", where it does NOT bind the item when (de)selection occurs! The multi-selection is simple to use with an ActionModeHelper to simplify your code with the ActionMode. Read the related Wiki page.



Currently, the selection is saved in a Set, but it might be delegated to the adapter item itself in the future. However, you can use 'selections' with this extension.






share|improve this answer

































    0














    The selection package is still in alpha, the documentation is quite poor and it's not really clear how to use it. I tried myself but I had similar problems, at the end I used the SmartRecyclerView






    share|improve this answer
























    • nowadays (from Sep, 2018), it has a stable 1.0.0 release

      – A. Petrov
      Nov 20 '18 at 8:53



















    0














    Two things:



    1) to reach the click on items, you need to implement an OnItemActivatedListener<K> listener and pass a reference to it onto the tracker builder. After that you can receive 'touches' on an items.



    2) to show Contextual Action Bar menu different approach is required: you need to implement an SelectionTracker.SelectionObserver and pass it to the tracker after creation: tracker.addObserver(.... After that, you can receive a selection change events in that observer (via onSelectionChanged callback). For instance, when selection starts (!tracker.getSelection().isEmpty() => show CAB) and selection ends (tracker.getSelection().isEmpty() hide CAB).
    If you want to control for single/multiple items selection, tracker must be supplemented with SelectionTracker.SelectionPredicate instance (via .withSelectionPredicate( builder method).



    and also, as @Code-Apprentice suggests, you need to provide correct ID's from getItemId() while you construct an ItemDetailsLookup.ItemDetails provider (this eliminates an Exception).






    share|improve this answer


























    • Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

      – Edric
      Dec 14 '18 at 3:23













    • @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

      – A. Petrov
      Dec 14 '18 at 7:14











    • Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

      – A. Petrov
      Dec 14 '18 at 7:23











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49545766%2fandroid-recyclerview-selection-implementation%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    I recently started looking at this library and got stuck on the same exception. The problem occurs when the SelectionTracker attempts to get an id from your custom RecyclerView.Adapter subclass. To fix the problem, first call setHasStableIds(true) in its constructor. Then override getItemId() to return an id for the given position parameter.






    share|improve this answer
























    • This should be the right answer

      – A. Petrov
      Nov 20 '18 at 6:25
















    4














    I recently started looking at this library and got stuck on the same exception. The problem occurs when the SelectionTracker attempts to get an id from your custom RecyclerView.Adapter subclass. To fix the problem, first call setHasStableIds(true) in its constructor. Then override getItemId() to return an id for the given position parameter.






    share|improve this answer
























    • This should be the right answer

      – A. Petrov
      Nov 20 '18 at 6:25














    4












    4








    4







    I recently started looking at this library and got stuck on the same exception. The problem occurs when the SelectionTracker attempts to get an id from your custom RecyclerView.Adapter subclass. To fix the problem, first call setHasStableIds(true) in its constructor. Then override getItemId() to return an id for the given position parameter.






    share|improve this answer













    I recently started looking at this library and got stuck on the same exception. The problem occurs when the SelectionTracker attempts to get an id from your custom RecyclerView.Adapter subclass. To fix the problem, first call setHasStableIds(true) in its constructor. Then override getItemId() to return an id for the given position parameter.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 11 '18 at 18:18









    Code-ApprenticeCode-Apprentice

    47k1489171




    47k1489171













    • This should be the right answer

      – A. Petrov
      Nov 20 '18 at 6:25



















    • This should be the right answer

      – A. Petrov
      Nov 20 '18 at 6:25

















    This should be the right answer

    – A. Petrov
    Nov 20 '18 at 6:25





    This should be the right answer

    – A. Petrov
    Nov 20 '18 at 6:25













    2














    New library looks complicated for now, indeed. I would wait the new final version before starting to implement over it. Surely, you can experiment with it, but I suggest you not use it in your app for now.



    There's only one nice, new feature: the continuous multi-selection by moving the finger or mouse.



    However, I found these examples:




    • https://github.com/Thumar/recyclerview-selection

    • https://github.com/guenodz/recyclerview-selection-demo

    • https://medium.com/@Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825


    In the meantime, I strongly suggest to use a library like mine: FlexibleAdapter which comes from more than 3 years of "selection experience", where it does NOT bind the item when (de)selection occurs! The multi-selection is simple to use with an ActionModeHelper to simplify your code with the ActionMode. Read the related Wiki page.



    Currently, the selection is saved in a Set, but it might be delegated to the adapter item itself in the future. However, you can use 'selections' with this extension.






    share|improve this answer






























      2














      New library looks complicated for now, indeed. I would wait the new final version before starting to implement over it. Surely, you can experiment with it, but I suggest you not use it in your app for now.



      There's only one nice, new feature: the continuous multi-selection by moving the finger or mouse.



      However, I found these examples:




      • https://github.com/Thumar/recyclerview-selection

      • https://github.com/guenodz/recyclerview-selection-demo

      • https://medium.com/@Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825


      In the meantime, I strongly suggest to use a library like mine: FlexibleAdapter which comes from more than 3 years of "selection experience", where it does NOT bind the item when (de)selection occurs! The multi-selection is simple to use with an ActionModeHelper to simplify your code with the ActionMode. Read the related Wiki page.



      Currently, the selection is saved in a Set, but it might be delegated to the adapter item itself in the future. However, you can use 'selections' with this extension.






      share|improve this answer




























        2












        2








        2







        New library looks complicated for now, indeed. I would wait the new final version before starting to implement over it. Surely, you can experiment with it, but I suggest you not use it in your app for now.



        There's only one nice, new feature: the continuous multi-selection by moving the finger or mouse.



        However, I found these examples:




        • https://github.com/Thumar/recyclerview-selection

        • https://github.com/guenodz/recyclerview-selection-demo

        • https://medium.com/@Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825


        In the meantime, I strongly suggest to use a library like mine: FlexibleAdapter which comes from more than 3 years of "selection experience", where it does NOT bind the item when (de)selection occurs! The multi-selection is simple to use with an ActionModeHelper to simplify your code with the ActionMode. Read the related Wiki page.



        Currently, the selection is saved in a Set, but it might be delegated to the adapter item itself in the future. However, you can use 'selections' with this extension.






        share|improve this answer















        New library looks complicated for now, indeed. I would wait the new final version before starting to implement over it. Surely, you can experiment with it, but I suggest you not use it in your app for now.



        There's only one nice, new feature: the continuous multi-selection by moving the finger or mouse.



        However, I found these examples:




        • https://github.com/Thumar/recyclerview-selection

        • https://github.com/guenodz/recyclerview-selection-demo

        • https://medium.com/@Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825


        In the meantime, I strongly suggest to use a library like mine: FlexibleAdapter which comes from more than 3 years of "selection experience", where it does NOT bind the item when (de)selection occurs! The multi-selection is simple to use with an ActionModeHelper to simplify your code with the ActionMode. Read the related Wiki page.



        Currently, the selection is saved in a Set, but it might be delegated to the adapter item itself in the future. However, you can use 'selections' with this extension.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 20 '18 at 23:24









        fmw42

        7,65841427




        7,65841427










        answered May 1 '18 at 13:49









        DavideasDavideas

        2,00521840




        2,00521840























            0














            The selection package is still in alpha, the documentation is quite poor and it's not really clear how to use it. I tried myself but I had similar problems, at the end I used the SmartRecyclerView






            share|improve this answer
























            • nowadays (from Sep, 2018), it has a stable 1.0.0 release

              – A. Petrov
              Nov 20 '18 at 8:53
















            0














            The selection package is still in alpha, the documentation is quite poor and it's not really clear how to use it. I tried myself but I had similar problems, at the end I used the SmartRecyclerView






            share|improve this answer
























            • nowadays (from Sep, 2018), it has a stable 1.0.0 release

              – A. Petrov
              Nov 20 '18 at 8:53














            0












            0








            0







            The selection package is still in alpha, the documentation is quite poor and it's not really clear how to use it. I tried myself but I had similar problems, at the end I used the SmartRecyclerView






            share|improve this answer













            The selection package is still in alpha, the documentation is quite poor and it's not really clear how to use it. I tried myself but I had similar problems, at the end I used the SmartRecyclerView







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 7 '18 at 8:19









            greywolf82greywolf82

            11.4k123773




            11.4k123773













            • nowadays (from Sep, 2018), it has a stable 1.0.0 release

              – A. Petrov
              Nov 20 '18 at 8:53



















            • nowadays (from Sep, 2018), it has a stable 1.0.0 release

              – A. Petrov
              Nov 20 '18 at 8:53

















            nowadays (from Sep, 2018), it has a stable 1.0.0 release

            – A. Petrov
            Nov 20 '18 at 8:53





            nowadays (from Sep, 2018), it has a stable 1.0.0 release

            – A. Petrov
            Nov 20 '18 at 8:53











            0














            Two things:



            1) to reach the click on items, you need to implement an OnItemActivatedListener<K> listener and pass a reference to it onto the tracker builder. After that you can receive 'touches' on an items.



            2) to show Contextual Action Bar menu different approach is required: you need to implement an SelectionTracker.SelectionObserver and pass it to the tracker after creation: tracker.addObserver(.... After that, you can receive a selection change events in that observer (via onSelectionChanged callback). For instance, when selection starts (!tracker.getSelection().isEmpty() => show CAB) and selection ends (tracker.getSelection().isEmpty() hide CAB).
            If you want to control for single/multiple items selection, tracker must be supplemented with SelectionTracker.SelectionPredicate instance (via .withSelectionPredicate( builder method).



            and also, as @Code-Apprentice suggests, you need to provide correct ID's from getItemId() while you construct an ItemDetailsLookup.ItemDetails provider (this eliminates an Exception).






            share|improve this answer


























            • Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

              – Edric
              Dec 14 '18 at 3:23













            • @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

              – A. Petrov
              Dec 14 '18 at 7:14











            • Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

              – A. Petrov
              Dec 14 '18 at 7:23
















            0














            Two things:



            1) to reach the click on items, you need to implement an OnItemActivatedListener<K> listener and pass a reference to it onto the tracker builder. After that you can receive 'touches' on an items.



            2) to show Contextual Action Bar menu different approach is required: you need to implement an SelectionTracker.SelectionObserver and pass it to the tracker after creation: tracker.addObserver(.... After that, you can receive a selection change events in that observer (via onSelectionChanged callback). For instance, when selection starts (!tracker.getSelection().isEmpty() => show CAB) and selection ends (tracker.getSelection().isEmpty() hide CAB).
            If you want to control for single/multiple items selection, tracker must be supplemented with SelectionTracker.SelectionPredicate instance (via .withSelectionPredicate( builder method).



            and also, as @Code-Apprentice suggests, you need to provide correct ID's from getItemId() while you construct an ItemDetailsLookup.ItemDetails provider (this eliminates an Exception).






            share|improve this answer


























            • Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

              – Edric
              Dec 14 '18 at 3:23













            • @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

              – A. Petrov
              Dec 14 '18 at 7:14











            • Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

              – A. Petrov
              Dec 14 '18 at 7:23














            0












            0








            0







            Two things:



            1) to reach the click on items, you need to implement an OnItemActivatedListener<K> listener and pass a reference to it onto the tracker builder. After that you can receive 'touches' on an items.



            2) to show Contextual Action Bar menu different approach is required: you need to implement an SelectionTracker.SelectionObserver and pass it to the tracker after creation: tracker.addObserver(.... After that, you can receive a selection change events in that observer (via onSelectionChanged callback). For instance, when selection starts (!tracker.getSelection().isEmpty() => show CAB) and selection ends (tracker.getSelection().isEmpty() hide CAB).
            If you want to control for single/multiple items selection, tracker must be supplemented with SelectionTracker.SelectionPredicate instance (via .withSelectionPredicate( builder method).



            and also, as @Code-Apprentice suggests, you need to provide correct ID's from getItemId() while you construct an ItemDetailsLookup.ItemDetails provider (this eliminates an Exception).






            share|improve this answer















            Two things:



            1) to reach the click on items, you need to implement an OnItemActivatedListener<K> listener and pass a reference to it onto the tracker builder. After that you can receive 'touches' on an items.



            2) to show Contextual Action Bar menu different approach is required: you need to implement an SelectionTracker.SelectionObserver and pass it to the tracker after creation: tracker.addObserver(.... After that, you can receive a selection change events in that observer (via onSelectionChanged callback). For instance, when selection starts (!tracker.getSelection().isEmpty() => show CAB) and selection ends (tracker.getSelection().isEmpty() hide CAB).
            If you want to control for single/multiple items selection, tracker must be supplemented with SelectionTracker.SelectionPredicate instance (via .withSelectionPredicate( builder method).



            and also, as @Code-Apprentice suggests, you need to provide correct ID's from getItemId() while you construct an ItemDetailsLookup.ItemDetails provider (this eliminates an Exception).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 '18 at 8:50

























            answered Nov 20 '18 at 8:41









            A. PetrovA. Petrov

            12616




            12616













            • Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

              – Edric
              Dec 14 '18 at 3:23













            • @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

              – A. Petrov
              Dec 14 '18 at 7:14











            • Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

              – A. Petrov
              Dec 14 '18 at 7:23



















            • Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

              – Edric
              Dec 14 '18 at 3:23













            • @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

              – A. Petrov
              Dec 14 '18 at 7:14











            • Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

              – A. Petrov
              Dec 14 '18 at 7:23

















            Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

            – Edric
            Dec 14 '18 at 3:23







            Where does the getItemId() method come from? It no longer exists in the RecyclerView Selection library in version 1.1.0-alpha01.

            – Edric
            Dec 14 '18 at 3:23















            @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

            – A. Petrov
            Dec 14 '18 at 7:14





            @Edric, this method is came from an Adapter. Override it, and provide from it correct id's of an Adapter hosted items. If Adapter do not provide an Id's, SelectionTracker do not know what to do with selection events - it can not hook into an items.

            – A. Petrov
            Dec 14 '18 at 7:14













            Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

            – A. Petrov
            Dec 14 '18 at 7:23





            Typically, you need to provide the result from Adapter's getItemId() via the overridden method getSelectionKey() of ItemDetailsLookup.ItemDetails. It is done while you write your own ViewHolder implementation.

            – A. Petrov
            Dec 14 '18 at 7:23


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49545766%2fandroid-recyclerview-selection-implementation%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            The term 'EXEC' is not recognized as the name of a cmdlet Powershell

            NPM command prompt closes immediately [closed]

            Error binding properties and functions in emscripten