I am trying to use the SwipeDismissBehavoir
from design support library. I've list items in RecyclerView
and swiping an item have to dismiss (like google inbox app) .
I've set the listener for the RecyclerView
items but the SwipeDismissBehavior
onDismiss
listener is not getting called.
SwipeDismissBehavior behavior = new SwipeDismissBehavior();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)mItemLayout.getLayoutParams();
params.setBehavior(behavior);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(View view) {
}
@Override
public void onDragStateChanged(int i) {
}
});
mItemLayout.setLayoutParams(params);
I have succeeded implementing the support library SwipeDismissBehavior and it actually requires CoordinatorLayout inside of each inflated card view layout. I haven't noticed any performance issues so far, so I assume CoordinatorLayout is not so heavy for the UI. There is probably a better way, but I still haven't found it.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF0000">
<LinearLayout
android:id="@+id/card_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#FFFFFF"
android:padding="20dp">
<TextView
android:id="@+id/card_context_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test text"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
In the constructor of the RecyclerView.ViewHolder implementation class (which is inside the Adapter) I have added:
View cardContentLayout = view.findViewById(R.id.card_content_layout);
SwipeDismissBehavior<View> swipeDismissBehavior = new SwipeDismissBehavior<>();
swipeDismissBehavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START);
swipeDismissBehavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(View view) {
int adapterPosition = getAdapterPosition();
deleteListener.onDismissGesture(view, adapterPosition);
}
@Override
public void onDragStateChanged(int state) { }
});
CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) cardContentLayout.getLayoutParams();
coordinatorParams.setBehavior(swipeDismissBehavior);
cardContentLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return swipeDismissBehavior.onTouchEvent((CoordinatorLayout) itemView, cardContentLayout, event);
}
});
Here is example how delete row by swipe
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
// init layout manager
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
final ArrayList<String> list = new ArrayList<String>();
list.add("Item1");
list.add("Item2");
list.add("Item3");
list.add("Item4");
list.add("Item5");
list.add("Item6");
final MyAdapter adapter = new MyAdapter(list);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// callback for drag-n-drop, false to skip this feature
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// callback for swipe to dismiss, removing item from data and adapter
list.remove(viewHolder.getAdapterPosition());
adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
});
swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
}
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<String> dataset_;
public static class MyViewHolder extends RecyclerView.ViewHolder{
public Button mBtn;
public TextView mTextView2;
public MyViewHolder(View v){
super(v);
mBtn = (Button) itemView.findViewById(R.id.delete);
mTextView2 = (TextView) itemView.findViewById(R.id.textView2);
}
}
public MyAdapter (ArrayList<String> dataset){
dataset_ = dataset;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(v);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder,int position){
holder.mTextView2.setText(dataset_.get(position));
}
@Override
public int getItemCount(){
return dataset_.size();
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical"
android:padding="16dp">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/heading_dismissable_recycler_view" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Item in RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="@+id/textView2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/delete"
android:text="Delete"
android:layout_marginLeft="150dp"
android:visibility="invisible" />
</LinearLayout>
</LinearLayout>
Tried with single view. I can know the view was dismissed, but I'm wondering how to restore the view like Gmail.
Layout:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coordinatorLayout"
tools:context=".MainActivity">
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Haha"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
</android.support.design.widget.CoordinatorLayout>
Activity:
public class MainActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
private CardView cardView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
cardView = (CardView) findViewById(R.id.cardView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) cardView.getLayoutParams();
final SwipeDismissBehavior<CardView> behavior = new SwipeDismissBehavior();
behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(final View view) {
Snackbar.make(coordinatorLayout, "Done", Snackbar.LENGTH_LONG)
.show();
}
@Override
public void onDragStateChanged(int i) {
}
});
params.setBehavior(behavior);
cardView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return behavior.onTouchEvent(coordinatorLayout, cardView, event);
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With