How to reset the recyclerview item after swiping using ItemTouchHelper - android

I have recyclerviewitem , on swiping left side , I am creating an image on the top of recyclerview item with the following code ,I am able to get the image on the top of the item but I am unable to reset the recyclerviewitem after swiping , rather its clearing the entire item
Code :
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT){
#Override
public boolean onMove(RecyclerView arg0,
RecyclerView.ViewHolder arg1,
RecyclerView.ViewHolder arg2) {
// TODO Auto-generated method stub
return false;
}
public void onChildDraw(android.graphics.Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && isCurrentlyActive) {
// Get RecyclerView item from the ViewHolder
View itemView = viewHolder.itemView;
Drawable d = ContextCompat.getDrawable(getContext(), R.drawable.swipeleft);
d.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
d.draw(c);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
};
#Override
public void onSwiped(
RecyclerView.ViewHolder viewHolder,
int Swipedir) {
}
};

Related

How to set the swipe threshold to half the screen?

I have a list (recycleView) of names. Some names are short, some are long. I want to delete them on swipe, but I want to make sure the user swipes more than half the distance of the screen (or width of list).
Currently it is going by the length of the individual item.
I know how to swipe on delete. I have tried overrideing getSwipeThreshold but again that uses the size of the item as its base.
Here's code because SO wants code:
RecyclerView recyclerView = findViewById(R.id.edit_list);
final MyRecyclerViewAdapter adapter = new
MyRecyclerViewAdapter(this, qnames);
//set swipe behavior
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false; //do not allow move
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// Row is swiped from recycler view
int position = viewHolder.getAdapterPosition(); //get position which is swipe
qnames.remove(position); //remove from display list
adapter.notifyItemRemoved(viewHolder.getLayoutPosition()); //update the view
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// view the background view
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
#Override
public float getSwipeThreshold( RecyclerView.ViewHolder viewHolder){
return .9f;
}
Here's some pictures.
So how do I set the swipe threshold to half the screen?
You must return 0.5f in getSwipeThreshold. This is default value, so just remove this override from your class&

disable few cells in recycleView from swipe or hide delete while swiping

I have a custom recycleView with swipe to delete option. I am able to display custom recycleView and also delete the item by swipping it. Swipe to delete is implement by using a separate class which implements SimpleCallback. Now, i want to disable the swipe to delete or dont show delete button while swipping for few items based on the username displaying in the RecycleView.
public class SwipeHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
SwipeHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((Adapter.ViewHolder) viewHolder).viewforeground;
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((Adapter.ViewHolder) viewHolder).viewforeground;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((Adapter.ViewHolder) viewHolder).viewforeground;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((Adapter.ViewHolder) viewHolder).viewforeground;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
}
And how I implemented
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new SwipeHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
Viewholder in recycleView.
public class ViewHolder extends RecyclerView.ViewHolder {
TextView uname,time,comm;
CircleImageView civ;
RelativeLayout viewBackground,viewforeground;
ViewHolder(View itemView) {
super(itemView);
civ = (CircleImageView)itemView.findViewById(R.id.profile_image);
uname = (TextView) itemView.findViewById(R.id.username);
time = (TextView) itemView.findViewById(R.id.time);
comm = (TextView) itemView.findViewById(R.id.comments);
viewBackground = (RelativeLayout)itemView.findViewById(R.id.view_background);
viewforeground = (RelativeLayout)itemView.findViewById(R.id.view_foreground);
}
}
Now i want to disable the swipe for the username which is not matching with uname in viewholder. I searched SO they ask to do change in SwipeDirs method but there i am not able to get the viewHolder values inside of it. Please help.
Override getMovementFlags in your ItemTouchHelper.SimpleCallback to check the view holder for the conditions that permit swiping as follows:
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int dragFlags = 0;
final int swipeFlags;
swipeFlags = ([OK to swipe this view])
? ItemTouchHelper.START | ItemTouchHelper.END
: 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
}

Android ItemTouchHelper.SimpleCallback get swipe direction

I have implemented swipe to dismiss into my recyclerview. It triggers 2 functions(editing of the record and deleting). If you swipe to the left, you edit it, if right, you delete it. I have such layout under the general part of the recyclerview item
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fe5722">
<ImageView
android:id="#+id/edit_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:src="#mipmap/ic_mode_edit_white_24dp" />
<ImageView
android:id="#+id/delete_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:src="#mipmap/ic_delete_white_24dp" />
</RelativeLayout>
So, if you swipe to the left (delete item) the left icon (for editing) should be hidden till the end of swipe. However, I have no idea how to get the swipe direction in the ItemTouchHelper.SimpleCallback class. Please help.
RecyclerItemTouchHelper.java
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
private ImageView imageView;
public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getLayout();
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getLayout();
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getLayout();
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).setEditIconInvisible();
final View foregroundView = ((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getLayout();
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return super.getSwipeDirs(recyclerView, viewHolder);
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
if(layoutDirection == ItemTouchHelper.LEFT){
Log.d("myLogs", "Налево пошло");
}
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
}
Update: I have solved the issue, just updated the onChildDraw method:
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getLayout();
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
if (dX > 0) {
((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getEditIcon().setVisibility(View.VISIBLE);
((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getDeleteIcon().setVisibility(View.GONE);
} else {
((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getEditIcon().setVisibility(View.GONE);
((PasswordRecyclerViewAdapter.ViewHolder) viewHolder).getDeleteIcon().setVisibility(View.VISIBLE);
}
}
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
ItemTouchHelper.Callback has a public method onChildDraw() that will be called on every frame with a dX value. This value is the horizontal translation of the view due to the current swipe action being performed by the user.
You can use the value of dX (and whether it is now positive when it was previously zero or now negative when it was previously zero) to detect whether the user is swiping left-to-right or right-to-left.
private class MyItemTouchCallback extends ItemTouchHelper.Callback {
private float previousDx = 0;
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
...
previousDx = 0;
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (previousDx <= 0 && dX > 0) {
// swiping from left to right
}
else if (previousDx >= 0 && dX < 0) {
// swiping from right to left
}
...
previousDx = dX;
}
}

Custom swipe ItemTouchHelper

Hi i have add ItemTouchHelper to my listview and i have do MyItemTouchHelper.attachToRecyclerView(myRecyclerView), then i have implements code for swipe to right:
private ItemTouchHelper itemTouchHelperEventi = 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 swipeDir) {
Evento ev = lista_eventi.get(viewHolder.getAdapterPosition());
analizzaEvento = new AnalizzaEvento(ev.getNome_evento());
adapterRecyclerViewEventi.remove(positionForResult);
adapterRecyclerViewEventi.notifyDataSetChanged();
}
});
Now i want to implement swipe code to remove item how gmail, i want that when i swipe to right background row becomes red and at left of row there is label undo and at right of row there is label delete (or confirm) if i click on right i delete item if i click on left return to the previous situation.
Please don't link other library i want to add this festure at my code without using external library, i don't want to rewrite all code only for this feature.
Is it possible?
Here is sample code
ItemTouchHelper.Callback simpleItemTouchCallback=new ItemTouchHelper.Callback() {
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//Unlock the movement of the item
//If you want only left to right unlock that moment only
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags;
if(viewHolder instanceof HeterogenousAdapter.ImageViewHolder)
swipeFlags = ItemTouchHelper.ANIMATION_TYPE_SWIPE_CANCEL ;
else
swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END ;
return makeMovementFlags(dragFlags, swipeFlags);
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//when user swiped this method getting call
int position = viewHolder.getAdapterPosition();
if (direction == ItemTouchHelper.LEFT){
adapter.removeItem(position);
}else {
removeView();
edit_position = position;
alertDialog.setTitle("Edit Country");
if (objectsArrayList.get(position) instanceof UserInfo){
UserInfo userInfo= (UserInfo) objectsArrayList.get(position);
et_country.setText(userInfo.getFirstName());
}else {
String abc= (String) objectsArrayList.get(position);
et_country.setText("ESHVAR");
}
alertDialog.show();
}
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
//when swiped started what you wants to do
//Here you can set Red color with icon on it
Bitmap icon;
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
View itemView = viewHolder.itemView;
float height=(float) itemView.getBottom() - (float) itemView.getTop();
float width =height/3;
if (dX > 0){
paint.setColor(Color.parseColor("#388e3c"));
RectF background = new RectF(
(float)itemView.getLeft(),
(float)itemView.getTop(),
dX,
(float)itemView.getBottom());
c.drawRect(background,paint);
icon = BitmapFactory.decodeResource(getResources(),R.drawable.action_search);
RectF icon_dest = new RectF(
(float)itemView.getLeft()+width,
itemView.getTop()+width,
(float)itemView.getLeft()+2*width,
(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,paint);
}else {
paint.setColor(Color.parseColor("#d32f2f"));
RectF background = new RectF(
(float)itemView.getRight()+dX,
(float)itemView.getTop(),
(float)itemView.getRight(),
(float)itemView.getBottom());
c.drawRect(background,paint);
icon =BitmapFactory.decodeResource(getResources(),R.drawable.action_search);
RectF icon_dest=new RectF(
(float)itemView.getRight()-2*width,
(float)itemView.getTop()+width,
(float)itemView.getRight() - width,
(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,paint);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
//Adding Recycle view to Item touch helper
ItemTouchHelper itemTouchHelper=new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);

ItemTouchHelper callback

I have problems understanding which callback method of ItemTouchHelper is called when i swipe a carditem, but i dont finish the swipe and instead turn it back to the normal state.
What i have currently:
#Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
mCardItemAdapter.deleteCard(viewHolder.getAdapterPosition(), mRecyclerView);
}
which removes the item from the adapter.
And:
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
Log.d("dx =",""+dX);
// Can be modified
if(dX < -300) {
View v = viewHolder.itemView;
RelativeLayout mLayout = (RelativeLayout) v.findViewById(R.id.card_item_layout_relative_layout);
mLayout.setBackgroundResource(R.color.red);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
What i want to achieve ? When i swipe, the background turns red, but when i release the swipe before onSwiped is called, the background stays red, but i want it to be white again.
Hope someone can help me out with this.
Add an additional else clause:
if(dx < -300){...} else { mLayout.setBackgroundResource(R.color.white); }

Categories

Resources