Pages

RecyclerView Drag/drop and Swipe

This extends my previous RecyclerView demo with Drag/drop and swipe features. Swiping a list item will delete it and drag/drop will be used to move items around.

To get this demo working first implement RecyclerView demo working and then make the following changes (code next to comments) to it; everything else remains the same.

MyAdapter.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    ArrayList<String> dataset;

    public MyAdapter (ArrayList<String> data) {
        dataset = data;
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtHeader;
        TextView txtFooter;

        ViewHolder (View v) {
            super(v);
            txtHeader = (TextView) v.findViewById(R.id.textView);
            txtFooter = (TextView) v.findViewById(R.id.textView2);
        }
    }

    void add (String item) {
        dataset.add(item);
        notifyItemInserted(dataset.indexOf(item));
    }

    void remove (String item) {
        int pos = dataset.indexOf(item);
        dataset.remove(pos);
        notifyItemRemoved(pos);
    }

    // removes item at pos
    void removePos (int pos) {
        dataset.remove(pos);
        notifyItemRemoved(pos);
    }

    // modify dataset as item is dragged
    void onItemMove (int fromPos, int toPos) {
        if (fromPos < toPos) {
            for (int i = fromPos; i < toPos; i++) {
                String s = dataset.get(i);
                String s2 = dataset.get(i+1);
                dataset.set(i, s2);
                dataset.set(i+1, s);
            }
        } else {
            for (int i = fromPos; i > toPos; i--) {
                String s = dataset.get(i);
                String s2 = dataset.get(i-1);
                dataset.set(i, s2);
                dataset.set(i-1, s);
            }
        }

        notifyItemMoved(fromPos, toPos);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        final String name = dataset.get(i);
        viewHolder.txtHeader.setText(name);
        viewHolder.txtFooter.setText("Footer: " + name);

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("testapp", "name "+name);
            }
        });
    }

    @Override
    public int getItemCount() {
        return dataset.size();
    }
}

MainActivity.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class MainActivity extends AppCompatActivity {
    MyAdapter adapter;
    int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayList<String> data = new ArrayList<String>();
        for (int i = 0; i < 5; i++) {
            count++;
            data.add("Test "+count);
        }

        // get recycler view from layout
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // set adapter
        adapter = new MyAdapter(data);
        recyclerView.setAdapter(adapter);

        // implementing drag / swipe
        ItemTouchHelper ith = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                return makeMovementFlags(
                        ItemTouchHelper.UP | ItemTouchHelper.DOWN,
                        ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
                );
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                adapter.removePos(viewHolder.getAdapterPosition());
            }
        });

        // linking drag/swipe to recyclerview
        ith.attachToRecyclerView(recyclerView);

        RecyclerView.LayoutManager lm = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(lm);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                adapter.add("New " + count);
            }
        });
    }
}