how to swipe item in recyclerview when using contentproviders - android

I want to swipe item from recyclerview and when item is swiped the bottom item should move up.
in onCreateView of my Fragment
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//Toast.makeText(getActivity(),"ByBy",Toast.LENGTH_LONG).show();
myListCursorAdapter.onItemRemove(viewHolder, recyclerView);
}
}).attachToRecyclerView(recyclerView);
in Adapter
public class TaskCursorAdapter extends RecyclerCursorAdapter<TaskCursorAdapter.ViewHolder> {
Context context;
Cursor cursor;
public TaskCursorAdapter(Context context, Cursor cursor) {
super(context, cursor);
this.cursor = cursor;
this.context = context;
setHasStableIds(true);
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView taskname;
public TextView dateDetails;
Context context;
Cursor cursor;
public ViewHolder(View view, Context context, Cursor cursor) {
super(view);
this.context = context;
this.cursor = cursor;
taskname = (TextView) view.findViewById(R.id.listitemtaskname);
dateDetails = (TextView) view.findViewById(R.id.listitemdatedetails);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// Form the content URI that represents the specific pet that was clicked on,
// by appending the "id" (passed as input to this method) onto the
// {#link PetEntry#CONTENT_URI}.
// For example, the URI would be "content://com.example.android.pets/pets/2"
// if the pet with ID 2 was clicked on.
Intent intent = new Intent(context, EditorActivity.class);
Uri currentPetUri = ContentUris.withAppendedId(TaskContract.TaskEntry.CONTENT_URI, this.getAdapterPosition() + 1);
intent.setData(currentPetUri);
context.startActivity(intent);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view, context, cursor);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
int taskColumnIndex = cursor.getColumnIndex(TaskContract.TaskEntry.NAME);
int dateColumnIndex = cursor.getColumnIndex(TaskContract.TaskEntry.DUEDATE);
int timeColumnIndex = cursor.getColumnIndex(TaskContract.TaskEntry.DUETIME);
String task = cursor.getString(taskColumnIndex);
String dateString = cursor.getString(dateColumnIndex);
String timeString = cursor.getString(timeColumnIndex);
viewHolder.cursor = cursor;
viewHolder.taskname.setText(task);
if (timeString == null && dateString == null) {
viewHolder.dateDetails.setVisibility(View.GONE);
} else {
viewHolder.dateDetails.setText(dateString + "\t\t" + timeString);
}
}
public void onItemRemove(final RecyclerView.ViewHolder viewHolder, final RecyclerView recyclerView) {
int adapterPosition = viewHolder.getAdapterPosition()+1;
Uri currentPetUri = ContentUris.withAppendedId(TaskContract.TaskEntry.CONTENT_URI, viewHolder.getAdapterPosition());
Snackbar snackbar = Snackbar
.make(recyclerView, "PHOTO REMOVED", Snackbar.LENGTH_LONG)
.setAction("UNDO", new View.OnClickListener() {
#Override
public void onClick(View view) {
int mAdapterPosition = viewHolder.getAdapterPosition() + 1;
Toast.makeText(context,"Hi",Toast.LENGTH_LONG).show();
recyclerView.scrollToPosition(mAdapterPosition);
}
});
snackbar.show();
context.getContentResolver().insert(TaskContract.TaskEntry.CONTENT_URI_FINISHED, values);
// Toast.makeText(context,"Hi2",Toast.LENGTH_LONG).show();
//notifyItemChanged(adapterPosition);
recyclerView.scrollToPosition(adapterPosition);
}
}
I tried everything but its difficult to swipe item from recyclerview and when undo of snackbar is pressed i want that item to reappear.I want to swipe item from recyclerview and when item is swiped the bottom item should move up.

1) You need to override the method onSwiped() as below.
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//do something
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int position = viewHolder.getAdapterPosition();
arrayList.remove(position);//remove swiped item
adapter.notifyDataSetChanged();//notify the recyclerview changes in the dataset
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(rv);//attach to your recyclerview
2) Don't forget to import v22.2.+ of the RecyclerView library.
3) For the botom item to move up(update) you need to do a refresh after "adapter.notifyDataSetChanged()" first update the database then pull the new data from the database(with changes). This will update the database and also the recyclerview.
4) To Undo you need to keep a stack of the elements that were removed(LIFO order) and insert them back as you click undo.

If you are using Content Provider you must call your cursor inside onSwiped method like this:
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(
0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
final int position = viewHolder.getLayoutPosition();
Cursor cursor = myListCursorAdapter.getCursor();
cursor.moveToPosition(x);
final long id = cursor.getLong(cursor.getColumnIndex(Your_Column_ID));
getActivity().getContentResolver().delete(Uri.withAppendedPath(YourContract.YOUR_URI, String.valueOf(id)), null, null);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(yourRecyclerView); //attach to your recyclerview
In your Adapter you must set getCursor():
public Cursor getCursor(){
return yourCursor;
}

Related

NestedRecyclerView's onBindViewHolder gettting called multiple times and not getting recycled

I am using nestedRecyclerView with Vertical parent recyclerview and horizontal child views. I have list of 10 items and each item contains a list for child recyclerview.
When I run the app, parent adapter's onbindviewholder getting called 10 items which is the total size of the parent list. I want to know why it is happening. It should call 4 or 5 onbindviewholder depending on the screen size but it is calling for all items which is unintended.
Parent Recyclerview initialization
homeRecyclerViewAdapter = new HomeRecyclerViewAdapter(getContext(), MR, (AppCompatActivity) getActivity());
homeRecyclerViewAdapter.setDataList(homeArrayList);
LinearLayoutManager mLinearLayoutManager3 = new LinearLayoutManager(getContext());
mLinearLayoutManager3.setOrientation(CustomLinearLayoutManager.VERTICAL);
homeRecyclerView.setLayoutManager(mLinearLayoutManager3);
homeRecyclerView.setAdapter(homeRecyclerViewAdapter);
Parent Adapter -
public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List dataList;
private Context mContext;
Typeface MR;
static String PACKAGE_NAME;
Utils utils;
CustomClickEvents customClickEvents;
AppCompatActivity appCompatActivity;
public HomeRecyclerViewAdapter(Context mContext, Typeface MR, int type, CustomClickEvents customClickEvents) {
this.mContext = mContext;
this.MR = MR;
this.customClickEvents = customClickEvents;
utils = new Utils();
}
RecyclerView.RecycledViewPool pool;
public HomeRecyclerViewAdapter(Context mContext, Typeface MR, AppCompatActivity appCompatActivity) {
pool = new RecyclerView.RecycledViewPool();
this.mContext = mContext;
this.MR = MR;
this.appCompatActivity = appCompatActivity;
utils = new Utils();
}
public void setDataList(List upiAppsList) {
this.dataList = upiAppsList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
PACKAGE_NAME = mContext.getPackageName();
if (viewType == Constants.HomePageViewTypes.TYPE_0) {
view = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_layout, null);
return new RecyclerViewHolder(view);
} else if (viewType == Constants.HomePageViewTypes.TYPE_1) {
view = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_layout, null);
return new RecyclerViewHolder(view);
} else if (viewType == Constants.HomePageViewTypes.TYPE_2) {
view = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_layout, null);
return new RecyclerViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder itemViewHolder, int position) {
Log.d("recyclerview", "HomeRecyclerViewHolder onbindviewholder + pos" + position);
Log.d("recyclerview", "HomeRecyclerViewHolder dataList.get(position):" + dataList.get(position));
RecyclerViewHolder holder = (RecyclerViewHolder) itemViewHolder;
holder.commonRecyclerViewAdapter.setDataList(((HomePageViewModel) dataList.get(position)).getDataList());
}
public void setbackgroundcolortoitem(int position, RecyclerViewHolder viewHolder, boolean is_checked) {
int modulus_position = position % 4;
Log.d("tag", "position ---- > " + modulus_position);
}
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
RecyclerView mRecyclerView;
CommonRecyclerViewAdapter commonRecyclerViewAdapter;
public RecyclerViewHolder(View itemView) {
super(itemView);
mRecyclerView = itemView.findViewById(R.id.mrecyclerview);
mRecyclerView.setPadding((int) (8 * utils.getScreenDensity(mContext)), 0, 0, (int) (8 * utils.getScreenDensity(mContext)));
// mRecyclerView.requestDisallowInterceptTouchEvent(false);
commonRecyclerViewAdapter = new CommonRecyclerViewAdapter(mContext, MR, 6, appCompatActivity);
LinearLayoutManager mLinearLayoutManager3 = new LinearLayoutManager(appCompatActivity, LinearLayoutManager.HORIZONTAL, false) {
#Override
public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
// force height of viewHolder here, this will override layout_height from xml
Log.d("upisdk", "HomeRecyclerView getwidth:" + getWidth());
lp.width = (int) (getWidth() / 1.6);
return true;
}
};
mLinearLayoutManager3.setOrientation(CustomLinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(mLinearLayoutManager3);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(commonRecyclerViewAdapter);
}
#Override
public void onClick(View v) {
int position = getLayoutPosition();
switch (v.getId()) {
case R.id.mainlayout:
break;
}
}
}
#Override
public int getItemCount() {
return dataList.size();
}
#Override
public int getItemViewType(int position) {
if (dataList.get(position) instanceof HomePageViewModel) {
if (((HomePageViewModel) dataList.get(position)).getLayoutType() == Constants.HomePageViewTypes.TYPE_0) {
return Constants.HomePageViewTypes.TYPE_0;
}
}
return -1;
}
}
I want parent onbindviewholder to get called for the items displaying currently on screen which is the supposed behaviour of RecyclerView.
Is the parent View of the Parent RecycleView a ScrollView or NestedScrollView, bro? If true, please remove it

How to change RecyclerView item color on Swipe?

I'm trying to make recyclerView item change color on swipe so it's will be highlited because on swipe i open an AlertDialog so the person will recognize which one item he is changing.
But my main issue is that when i try to change the background color by using
viewHolder.itemView.setBackgroundColor(Color.parseColor("#cc0000"));
Nothing is heppening, here is my full code from the builder of recyclerView
public void buildTopRecyclerView(){
mRecyclerViewTOP = findViewById(R.id.listView);
mRecyclerViewTOP.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
exampleAdapter = new ExampleAdapter(itemCassas);
mRecyclerViewTOP.setLayoutManager(mLayoutManager);
mRecyclerViewTOP.setAdapter(exampleAdapter);
// onSwipe();
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
if (direction == ItemTouchHelper.RIGHT) {
customAllertDelete(position);
viewHolder.itemView.setBackgroundColor(Color.parseColor("#cc0000"));
exampleAdapter.notifyDataSetChanged();
}
if (direction == ItemTouchHelper.LEFT) {
customAllertQuantity(position);
}
}
}).attachToRecyclerView(mRecyclerViewTOP);
}
And here is also the Adapter code if it could be usefull
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private ArrayList<ItemCassa> mExampleList;
#NonNull
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerlist_item,parent,false);
return new ExampleViewHolder(v);
}
ExampleAdapter(ArrayList<ItemCassa> exampleList){
mExampleList = exampleList;
}
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder holder, int position) {
ItemCassa item = mExampleList.get(position);
holder.desc.setText(item.getBtnName());
holder.qta.setText(String.valueOf(item.getQuant()));
holder.imp.setText(String.valueOf((new DecimalFormat("#0.00").format(item.getPrice()))));
if(position % 2 == 0 ){
holder.itemView.setBackgroundColor(Color.parseColor("#C0C0C0"));
holder.desc.setBackgroundColor(Color.parseColor("#C0C0C0"));
holder.qta.setBackgroundColor(Color.parseColor("#C0C0C0"));
holder.imp.setBackgroundColor(Color.parseColor("#C0C0C0"));
}else if(position % 2 == 1){
holder.itemView.setBackgroundColor(Color.parseColor("#D3D3D3"));
holder.desc.setBackgroundColor(Color.parseColor("#D3D3D3"));
holder.qta.setBackgroundColor(Color.parseColor("#D3D3D3"));
holder.imp.setBackgroundColor(Color.parseColor("#D3D3D3"));
}
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public static class ExampleViewHolder extends RecyclerView.ViewHolder {
public TextView desc;
public TextView qta;
public TextView imp;
ExampleViewHolder(View itemView) {
super(itemView);
desc = itemView.findViewById(R.id.Desc);
qta = itemView.findViewById(R.id.Qta);
imp = itemView.findViewById(R.id.Imp);
}
}
public void removeItem(int position) {
mExampleList.remove(position);
notifyItemRemoved(position);
}
}
Here is the gif that "explain" a bit what i'm trying to do, as you can see on swipe it's open an AlertDialog and turn back the selected item, but now i would color that selected item background until the user make a choose in the AlertDialog
Try using like this:
First of all in your onSwiped method call your adapter's method and pass the required parameters.
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int swipedPosition = viewHolder.getAdapterPosition();
YourAdapter adapter = (YourAdapter) rlCartList.getAdapter();
adapter.remove(swipedPosition); // I was removing items so you
can change the name of method as you like
}
Now in your adapter do something like this:
public void remove(int position) {
YourModel item = cartItems.get(position);
if (cartItems.contains(item)) {
ViewHolder.tvItemName.setBackgroundColor(mContext.getResources().getColor(R.color.grey));
notifyDataSetChanged();
}
}
One more thing is you will need to make your textView or the view you are assigning the background to Static. And I have tested this code it's running fine in my project the background of textView changes on swipe.
Tell me if you need further assistance. And also one more thing you can use your alert dialog in adapter too :)

Make onClickListener accessible in Activity from RecyclerViewAdapter

Actually in my RecyclerView i'm able to create Child items by programmatically adding view and TextView.
I even have a onClickListener for my parent item from the same RecyclerView and i've added a onClick method for my Child view's but now my main issue is how can i use the Child onClick in my Activity?
Here is my Adapter code
public class AdapterPTERM extends RecyclerView.Adapter<AdapterPTERM.ExampleViewHolder> {
private List<ItemPTERM> mExampleList;
private final LayoutInflater mInflater;
private OnItemClickListener mListener;
// ONCLICK FOR THE CHILD ITEMS
private View.OnClickListener varientClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.getTag()!= null){
int position = (int) v.getTag();
}
}
};
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
#NonNull
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_pterm,parent,false);
return new ExampleViewHolder(v,mListener);
}
AdapterPTERM(Context context, List<ItemPTERM> exampleList){
mExampleList = exampleList;
mInflater = LayoutInflater.from(context);
}
#Override
public void onBindViewHolder(#NonNull final ExampleViewHolder holder, final int position) {
final ItemPTERM item = mExampleList.get(position);
holder.desc.setText(item.getBtnName());
holder.qta.setText(String.valueOf(item.getQuant()));
holder.variantsContainer.removeAllViews();
// CREATING CHILD ITEM
List<Variant> variants = item.getVariants();
if (variants != null && variants.size() > 0){
for(Variant v : variants){
View vView = mInflater.inflate(R.layout.variant_layout,holder.variantsContainer,false);
TextView nameTV = vView.findViewById(R.id.variant_name);
nameTV.setText(v.getName());
vView.setTag(position);
vView.setOnClickListener(varientClickListener);
holder.variantsContainer.addView(vView);
}
}
// NOT IMPORTANT (CHANGING FIELDS COLOR)
if(position % 2 == 0 ){
holder.itemView.setBackgroundColor(Color.parseColor("#C0C0C0"));
}else if(position % 2 == 1){
holder.itemView.setBackgroundColor(Color.parseColor("#D3D3D3"));
}
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder {
public TextView desc;
public TextView qta;
private LinearLayout variantsContainer;
ExampleViewHolder(View itemView, final OnItemClickListener listener) {
super(itemView);
desc = itemView.findViewById(R.id.Desc);
qta = itemView.findViewById(R.id.Qta);
variantsContainer = itemView.findViewById(R.id.ll_child_items);
// onClick method for Parent Item
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
public void removeItem(int position) {
mExampleList.remove(position);
notifyItemRemoved(position);
}
public void removeVariant(int position,int positionbtn){
mExampleList.get(positionbtn).getVariants().remove(position);
notifyDataSetChanged();
}
}
While here is my code from the Activity where i build my RecyclerView and here i'm using the onClick for the parent for make appear an AlertDialog but i would be able to make appear that AlertDialog by clicking onChild instead of parent.
public void buildTopRecyclerView() {
mRecyclerViewTOP = findViewById(R.id.listView);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
exampleAdapter = new AdapterPTERM(this,dummyDataItems);
mRecyclerViewTOP.setLayoutManager(mLayoutManager);
mRecyclerViewTOP.setAdapter(exampleAdapter);
mRecyclerViewTOP.setHasFixedSize(true);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
if (direction == ItemTouchHelper.RIGHT) {
customAllertDelete(position);
exampleAdapter.notifyItemChanged(position);
}
if (direction == ItemTouchHelper.LEFT) {
customAllertQuantity(position);
exampleAdapter.notifyItemChanged(position);
}
}
}).attachToRecyclerView(mRecyclerViewTOP);
exampleAdapter.setOnItemClickListener(new AdapterPTERM.OnItemClickListener() {
#Override
public void onItemClick(int position) {
if (dummyDataItems.get(position).getVariants() != null) {
customAlertVar(position);
}else {
//
}
}
});
}
SOLVED
I just had to remove
// ONCLICK FOR THE CHILD ITEMS
private View.OnClickListener varientClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.getTag()!= null){
int position = (int) v.getTag();
}
}
};
From my adapter as it was handling another click and was blocking the AlertDialog and even removed the
vView.setTag(position);
vView.setOnClickListener(varientClickListener);

adding swipe inside onBindViewHolder RecyclerView

hey guys Im trying to use swipe inside onBindViewHolder because my items are from the database but I think it doesnt seem to work cuz my app is crashing. Im using this custom cursor adapter for my recyclerview https://gist.github.com/skyfishjy/443b7448f59be978bc59 here is my code.
#Override
public void onBindViewHolder(ItemViewHolder viewHolder, Cursor cursor) {
mItems = cursor;
final int id = cursor.getInt(cursor.getColumnIndex(MyDBHandler.COLUMN_ID));
final String title = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_TITLE_REMINDER));
final String desc = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_DESC_REMINDER));
final String date = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_DATE_REMINDER));
viewHolder.title.setText(title);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, String.valueOf(id), Toast.LENGTH_SHORT).show();
}
});
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int itemPosition = viewHolder.getAdapterPosition();
notifyItemRemoved(itemPosition);
dbHandler.deleteReminder(id);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(this.myRecyclerview);
}
Is there anyway I can do swiping to dismiss my items in recyclerview?
Remove the following chunk of code from onBindViewHolder and add in your activity or fragment from where you are initializing adapter.
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { // type cast your view holder
// CusrsorViewHolder cViewHolder = (CursorViewHolder)viewHolder;
int itemPosition = viewHolder.getAdapterPosition();
notifyItemRemoved(itemPosition);
dbHandler.deleteReminder(cViewHolder.id);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(this.myRecyclerview);
//put the above code before the following method in your activity or fragment
//this.RecylerView.setAdapter(adapter)
Set your id in onBindViewHolder
#Override
public void onBindViewHolder(ItemViewHolder viewHolder, Cursor cursor) {
mItems = cursor;
final int id = cursor.getInt(cursor.getColumnIndex(MyDBHandler.COLUMN_ID));
viewHolder.id = id;
}
thanks to #Waleed Sarwar for helping me solve it.
I was using https://gist.github.com/skyfishjy/443b7448f59be978bc59 for my recyclerviewcursoradapter.
MainActivity.java
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
RemindersAdapter.ItemViewHolder itemViewHolder = (RemindersAdapter.ItemViewHolder)viewHolder;
int itemPosition = itemViewHolder.getAdapterPosition();
adapter.notifyItemRemoved(itemPosition);
// get the id of an item via itemViewHolder.id
dbHandler.deleteReminder(itemViewHolder.id);
// update cursor upon deleting do avoid
// the card from coming back upon swipe
adapter.swapCursor(dbHandler.getAllReminders());
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(listReminder);
RemindersAdapter.java
#Override
public void onBindViewHolder(ItemViewHolder viewHolder, Cursor cursor) {
final int id = cursor.getInt(cursor.getColumnIndex(MyDBHandler.COLUMN_ID));
final String title = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_TITLE_REMINDER));
final String desc = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_DESC_REMINDER));
final String date = cursor.getString(cursor.getColumnIndex(MyDBHandler.COLUMN_DATE_REMINDER));
viewHolder.title.setText(title);
// pass id to viewholder to get in swipe
viewHolder.id = id;
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
public int id;
TextView title;
public ItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.reminderTitle);
}
}
Im using adapter.swapCursor(dbHandler.getAllReminders()); from my adapter which was a method from abstract class CursorRecyclerViewAdapter that makes the cursor updated upon deleting because without it, the deleted item will be recreated by onBindViewHolder.
Use the below code to delete the item from the list. orderlist is the RecyclerView variable.
SwipeDismissRecyclerViewTouchListener touchListener =
new SwipeDismissRecyclerViewTouchListener(
orderlist,
new SwipeDismissRecyclerViewTouchListener.DismissCallbacks() {
#Override
public boolean canDismiss(int position) {
return true;
}
#Override
public void onDismiss(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
/*db.deleteOrderProduct(ordereditems.get(position).getOrder_pro_Code());
if(position>1){
listposition = position-1;
}*/
//ordereditems.remove(position);
//adapter.notifyItemRemoved(position);
//adapter.notifyDataSetChanged();
//displayOrderList();
DeleteOrderById(position);
}
adapter.notifyDataSetChanged();
}
});
orderlist.setOnTouchListener(touchListener);

Removing item from a custom RecycleView adapter with swiping right messes up with the item order

I have an ArrayList<String> with 6 items {"1", "2", "3", "4", "5", "6"}.
I am representing these items with a CardView. I want to remove the items with swiping left.
It looks like this: http://imgur.com/cuWoiB3
When I swipe right from number 2, it looks like this: http://imgur.com/5E9fwP0
If I remove Number 5, it removes number 2. If I remove number 3, it removes number 1. It seems to be completely random.
Am I missing something here? How do I fix this?
Relevant code:
My adapter:
public class ChoresAdapter extends RecyclerView.Adapter<ChoresAdapter.ChoreViewHolder>{
private ArrayList<String> chores;
public ChoresAdapter(ArrayList<String> chores){
this.chores = chores;
}
#Override
public ChoreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_cardview, parent, false);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
ChoreViewHolder pvh = new ChoreViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(ChoreViewHolder holder, int position) {
holder.choreName.setText(this.chores.get(position));
}
#Override
public int getItemCount() {
return this.chores.size();
}
public void removeAt(int position) {
this.chores.remove(position);
notifyItemRemoved(position);
notifyDataSetChanged();
}
public static class ChoreViewHolder extends RecyclerView.ViewHolder {
CardView cv;
public static TextView choreName;
public static TextView personAge;
public static ImageView personPhoto;
ChoreViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
choreName = (TextView)itemView.findViewById(R.id.chore_name);
}
}
}
Relevant code in my fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_chores, container, false);
RecyclerView rv = (RecyclerView)view.findViewById(R.id.rv);
rv.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
chores = new ArrayList<>();
chores.add("1");
chores.add("2");
chores.add("3");
chores.add("4");
chores.add("5");
chores.add("6");
adapter = new ChoresAdapter(chores);
SwipeableRecyclerViewTouchListener swipeTouchListener =
new SwipeableRecyclerViewTouchListener(rv,
new SwipeableRecyclerViewTouchListener.SwipeListener() {
#Override
public boolean canSwipe(int position) {
return true;
}
#Override
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.removeAt(position);
}
}
#Override
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.removeAt(position);
}
}
});
rv.addOnItemTouchListener(swipeTouchListener);
rv.setAdapter(adapter);
return view;
}
Its bit late, I just fall into the same situation and got answer, Just use
chores.remove(position);
adapter.notifyDataSetChanged();
You dont need to do that on the adapter class.
You can use below code (ItemTouchHelper.SimpleCallback from Android support V7) to remove the cards from RecyclerView using swipe gesture. You need to remove element from your ArrayList as well when you swipe it from RecyclerView.
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
chores.remove(viewHolder.getAdapterPosition());
adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
#Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recList);

Categories

Resources