Make Recycler view item non-swipable - android

In my recycler view, I need to set the header item non-swipable. I override the methods getSwipeDirs() and getMovementFlags() and returns 0 for the header position,but now also its able to swipe. What is wrong with my code.
Nb:I set my swiping to one direction only(left to right)
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import com.example.shanto.inventory.adapters.MaterialAdapter;
import com.example.shanto.inventory.adapters.MaterialDetailAdapter;
public class RecyclerItemTouchHelper_MaterialDetail extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
public RecyclerItemTouchHelper_MaterialDetail(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
/* #Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
*//*if (viewHolder instanceof MaterialDetailAdapter.HeaderVH) return 0;
return super.getSwipeDirs(recyclerView, viewHolder);*//*
int position = viewHolder.getAdapterPosition();
return position == 0 ? 0 : super.getSwipeDirs(recyclerView, viewHolder);
}*/
#Override
public int getMovementFlags(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof MaterialDetailAdapter.HeaderVH){
return makeMovementFlags(0, 0);
} else {
return makeMovementFlags(0, super.getSwipeDirs(recyclerView, viewHolder));
}
}
#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 = ((MaterialDetailAdapter.MaterialVH) viewHolder).item;
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 = ((MaterialDetailAdapter.MaterialVH) viewHolder).item;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((MaterialDetailAdapter.MaterialVH) viewHolder).item;
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 = ((MaterialDetailAdapter.MaterialVH) viewHolder).item;
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);
}
}
Here I update the code used for swiping

Sorry guys, I use the below code for swiping in activity
ItemTouchHelper.SimpleCallback itemTouchHelperCallback1 = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT ) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// Row is swiped from recycler view
// remove it from adapter
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
where SimpleCallback(0, ItemTouchHelper.LEFT ) makes the item swipe always left,that makes me confused.

Related

Detaching item touch helper callback from recycler view

How do I go about doing this for a swipe action for items in a recycler view?
This is my item touch helper class:
public class RecyclerTouchHelper extends ItemTouchHelper.SimpleCallback {
private final RecyclerTouchHelperListener listener;
boolean swipeAllowed;
private static final String TAG = RecyclerTouchHelper.class.getSimpleName();
public RecyclerTouchHelper(int dragDirs, int swipeDirs, RecyclerTouchHelperListener listener, boolean swipeAllowed) {
super(dragDirs, swipeDirs);
this.listener = listener;
this.swipeAllowed = swipeAllowed;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(#NonNull Canvas c, #NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void clearView(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAbsoluteAdapterPosition());
}
#Override
public boolean isItemViewSwipeEnabled() {
return swipeAllowed;
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
}
And this is a function in the fragment/activity that is triggered via an action from the recycler adapter:
ItemTouchHelper.SimpleCallback itemTouchHelperCallback;
#Override
public void onScrollCheck(boolean allowSwipe) {
if (!allowSwipe) {
itemTouchHelperCallback = new RecyclerTouchHelper(0, 0, this, false);
itemTouchHelperCallback = null;
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(null);
} else {
itemTouchHelperCallback = new RecyclerTouchHelper(0, ItemTouchHelper.LEFT, this, true);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mealplanRecycler);
}
}
My problem is that no matter what I do, once swiping is turned on it remains allowed and I cannot turn it off. Is it something I am doing wrong when defining and assigning the callback?
Where are you setting swipeAllowed back to false?
You seem to be setting it true first time round and then keep hitting
else {
itemTouchHelperCallback = new RecyclerTouchHelper(0, ItemTouchHelper.LEFT, this, true);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mealplanRecycler);
}
As it was never set back to false?

how to restore recycler view item after swipe

I have a recyclerview and I've add swipe to it with itemtouchhelper class and it works fine, there is 2 views in layout that foreground view moves on swipe over bacjground layer, problem is I want to foreground view get the previous location after swipe , like swipe effect that make call in Samsung phones.
I can make that with calling notifyitemchanged after swipe. but I works one time and if I swipe again on that item, view is not restored
this is my itemtouchhelper class
public class RecyclerItemTouchHelperlog extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
public RecyclerItemTouchHelperlog(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((recycleAdapterlog.MyViewHolder) viewHolder).logitm;
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 = ((recycleAdapterlog.MyViewHolder) viewHolder).logitm;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void clearView(#NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((recycleAdapterlog.MyViewHolder) viewHolder).logitm;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public int getSwipeDirs(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder) {
View hv=((recycleAdapterlog.MyViewHolder) viewHolder).hv;
if(hv==null)return super.getSwipeDirs(recyclerView, viewHolder);
else if(hv.getVisibility()==View.VISIBLE)return 0;
else return super.getSwipeDirs(recyclerView, viewHolder);
}
#Override
public void onChildDraw(Canvas c, #NonNull RecyclerView recyclerView,
#NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((recycleAdapterlog.MyViewHolder) viewHolder).logitm;
final View swipel = ((recycleAdapterlog.MyViewHolder) viewHolder).swipelogleft;
final View swiper = ((recycleAdapterlog.MyViewHolder) viewHolder).swipelogright;
if(dX<0){
swipel.setVisibility(View.VISIBLE);
swiper.setVisibility(View.GONE);
}
else {
swipel.setVisibility(View.GONE);
swiper.setVisibility(View.VISIBLE);
}
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
final Float alpha =1 - Math.abs (dX) / ( viewHolder.itemView.getWidth ());
foregroundView.setAlpha (alpha);
foregroundView.setTranslationX (dX);
}
recentconfrag.swipedlog=true;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void onSwiped(#NonNull 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);
}
}
I don't know, where is a problem, I tested the solution below on emulator and Samsung Galaxy S4.
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
#Override
public boolean onMove(#NotNull RecyclerView recyclerView,
#NotNull RecyclerView.ViewHolder viewHolder,
#NotNull RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder instanceof YourAdapter.ItemViewHolder) {
final View foregroundView = ((YourAdapter.ItemViewHolder) viewHolder).getItem();
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(#NotNull Canvas c, #NotNull RecyclerView recyclerView,
#NotNull RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
if (viewHolder instanceof YourAdapter.ItemViewHolder) {
final View foregroundView = ((YourAdapter.ItemViewHolder) viewHolder).getItem();
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
}
#Override
public void clearView(#NotNull RecyclerView recyclerView, #NotNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof YourAdapter.ItemViewHolder) {
final View foregroundView = ((YourAdapter.ItemViewHolder) viewHolder).getItem();
getDefaultUIUtil().clearView(foregroundView);
}
}
#Override
public void onChildDraw(#NotNull Canvas c, #NotNull RecyclerView recyclerView,
#NotNull RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
if (viewHolder instanceof YourAdapter.ItemViewHolder) {
final View foregroundView = ((YourAdapter.ItemViewHolder) viewHolder).getItem();
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
}
#Override
public void onSwiped(#NotNull RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
}
Then use it in a fragment.
class YourFragment : Fragment(), RecyclerItemTouchHelper.RecyclerItemTouchHelperListener {
private var adapter: YourAdapter? = null
private lateinit var itemTouchHelperCallback: RecyclerItemTouchHelper
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(LAYOUT, container, false)
adapter = YourAdapter(this)
view.recycler_view.run {
layoutManager = LinearLayoutManager(context)
adapter = this#YourFragment.adapter
setHasFixedSize(true)
// attaching the touch helper to recycler view
itemTouchHelperCallback =
RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this#YourFragment)
ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(this)
}
return view
}
// callback when recycler view is swiped
// item will be removed on swiped
override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int, position: Int) {
// if (viewHolder is YourAdapter.ItemViewHolder) {
// remove the item from recycler view
// This is a custom dialog with "Yes", "No" buttons.
showDialog("Remove the item?",
{ adapter?.removeAt(position) },
{ adapter?.notifyItemChanged(position) })
// }
}
Notice that I use position in onSwiped, but viewHolder.getAdapterPosition() is also right. I used a solution for reverting an item from Android RecyclerView ItemTouchHelper revert swipe and restore view holder.

RecyclerView swiping to delete in Fragment?

I'm trying to create a feature where if the user swipes LEFT on an item in the RecyclerView, the item will be deleted.
My RecyclerView is inside a Fragment which is inside a FrameLayout controlled by a BottomNavigation.
I have the code where it works when the RecyclerView is in its own Activity but when I transfer it into a Fragment, the swiping functionality breaks. I'm unable to swipe at all.
In my Fragment, I'm extending the RecyclerItemTouchHelperListener interface.
interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
Then I create a Callback
ItemTouchHelper.SimpleCallback ItemTouchHelperCallbackLeft = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(ItemTouchHelperCallbackLeft).attachToRecyclerView(recyclerView);
Now I create a function called OnSwiped to handle the swiping.
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
if (viewHolder instanceof ListAdapter.ViewHolder) {
if (direction == ItemTouchHelper.LEFT) {
String cityName = stationList.get(viewHolder.getAdapterPosition()).getData().getCity();
//Create a backup of the deleted item in case user wants to undo delete
Station deletedStation = stationList.get(viewHolder.getAdapterPosition());
int deletedStationIndex = viewHolder.getAdapterPosition();
//Remove the item from RecyclerView
listAdapter.removeItem(deletedStationIndex);
Snackbar snackbar = Snackbar.make(coordinatorLayout, cityName + " removed from list!", Snackbar.LENGTH_LONG);
snackbar.setAction("UNDO", new View.OnClickListener() {
#Override
public void onClick(View view) {
// undo is selected, restore the deleted item
listAdapter.restoreItem(deletedStation, position);
}
});
snackbar.show();
}
}
}
And here is the RecyclerItemTouchHelper class.
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
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 onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((ListAdapter.ViewHolder) viewHolder).listViewForeground;
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(Canvas canvas, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((ListAdapter.ViewHolder) viewHolder).listViewForeground;
getDefaultUIUtil().onDrawOver(canvas, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((ListAdapter.ViewHolder) viewHolder).listViewForeground;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public void onChildDraw(Canvas canvas, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((ListAdapter.ViewHolder) viewHolder).listViewForeground;
getDefaultUIUtil().onDraw(canvas, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
}
Keep in mind that everything works when the RecyclerView is inside its own Activity, but when I transfer my RecyclerView into a Fragment this swiping function does not work.
I've fixed my issue by moving the Callback after I initialize my RecyclerView.
recyclerView = itemView.findViewById(R.id.recyclerView);
ItemTouchHelper.SimpleCallback ItemTouchHelperCallbackLeft = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(ItemTouchHelperCallbackLeft).attachToRecyclerView(recyclerView);

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;
}
}

Categories

Resources