Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SwipeDismissBehavior.OnDismissListener on RecyclerView

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);
like image 658
Libin Avatar asked May 30 '15 18:05

Libin


3 Answers

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);
    }
});
like image 54
Galya Avatar answered Oct 11 '22 02:10

Galya


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>
like image 41
Waran- Avatar answered Oct 11 '22 02:10

Waran-


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


}
like image 28
Leo Lin Avatar answered Oct 11 '22 03:10

Leo Lin