[Java] Note how to use RecyclerView and implementation of animated swipe processing.

1.First of all

1.1 Refusal

** This site links some posts in Qiita. If you find it unpleasant, please comment. We will correspond. ** **

1.2 Purpose

RecyclerView is very convenient. I'm using it instead of ListView, but I'll forget how to implement it and how to implement swipe, so I'll make a note here. The swipe animation mimics the Gmail email delete swipe.

2. RecyclerView body

This implementation is the same as "Basics of RecyclerView" by @ naoi. It is explained in a very easy-to-understand manner. The mechanism of RecyclerView is a little complicated, so it's a good idea to remember the figure.

Here, we will produce the following four.

** This time, let's put the data as an image and a character string. ** **

2.1 Determine the layout of a row (adapter_row.xml)

Determine the layout of a row of RecyclerView.

adapter_row


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/imageView_adapter_show_bitmap"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/textView_adapter_show_string"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</android.support.constraint.ConstraintLayout>

2.2 Create a structure (DataModel.java)

There is no structure in Java, but you can substitute Class.

DataModel.java



public class DataModel {
    private Bitmap mBitmap;
    private String mString;

    public Bitmap getBitmap () {
        return mBitmap;
    }

    public String getString () {
        return mString;
    }

    public void setBitmap (Bitmap mBitmap) {
        this.mBitmap = mBitmap;
    }

    public void setString (String mString) {
        this.mString = mString;
    }
}

Isn't it common to add m to member variables?

As an aside, "get ~" and "set ~" are said to be `getter / setter```, but in ```Android Studio, if you hit public, the member variable It seems to make `getter / setter. I'm grateful that if I change the name a little, it's complete.

2.3 Get View in one line (ViewHolder.java)

Create a ViewHolder. Here, xml body is not specified, but View in one line is findViewByID ().

ViewHolder.java



public class ViewHolder extends RecyclerView.ViewHolder {
    public ImageView mImageView;
    public TextView mTextView;
    
    //constructor
    public ViewHolder (@NonNull View itemView) {
        super(itemView);
        mImageView = itemView.findViewById(R.id.imageView_adapter_show_bitmap);
        mTextView = itemView.findViewById(R.id.textView_adapter_show_string);
    }
}

When the constructor inherits RecyclerView.ViewHolder, it is required to add ```itemView`` to the argument.

2.4 Place data (Adapter.java)

Adapter.java



public class Adapter extends RecyclerView.Adapter<ViewHolder> {

    private List<DataModel> insertDataList;

    public Adapter (List<DataModel> list) {
        this.insertDataList = list;
    }

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

    @Override
    public void onBindViewHolder (@NonNull ViewHolder viewHolder, int i) {
        noteViewHolder.mImageView.setImageBitmap(insertDataList.get(i).getBitmap());
        noteViewHolder.mTextView.setText(insertDataList.get(i).getString());
    }

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

3. How to use

The usage in `ʻActivity`` etc. is as follows. ** Adapter may conflict with others ... (I actually give it a different name) **

MainActivity.java


public class RegisterNoteActivity extends AppCompatActivity {
    RecyclerView mRecyclerViewList;

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

        mRecyclerViewList = findViewById(R.id.recyclerView_main);

        LinearLayoutManager manager = new LinearLayoutManager(this);
        mRecyclerViewList.setHasFixedSize(false);
        mRecyclerViewList.setLayoutManager(manager);
        mRecyclerViewList.setAdapter(new Adapter(createData()));
    }

    private List<NoteDataModel> createData() {
        List<NoteDataModel> list = new ArrayList<>();
        for (int index = 0; index < 100; index++) {
            //One line of data
            NoteDataModel rowData = new NoteDataModel();
            rowData.setBitmap(/*Some kind of image*/);
            rowData.setmString("This line is" + (index + 1) + "This is the second repetition.");
            list.add(rowData);
        }
        return list;
    }
}

4. Swipe

Let's implement an animated swipe. To tell the truth, if you implement swipe, you will get an animation that shifts sideways or snaps away. ** Colors and icons don't come with it, so you can implement it here. This time, ** delete only when swiping left **. The color is red and the icon is ** your own ** trash can mark.

MainActivity.java


    // ...abridgement
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register_note);
        // ...abridgement...
        mRecyclerViewList.setAdapter(new Adapter(createData())); //A little while ago
        //Add from here
        final Drawable deleteIcon = ContextCompat.getDrawable(this, R.drawable.ic_action_delete);
        ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {

            @Override
            public boolean onMove (@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
                return false;
            }

            @Override
            public void onSwiped (@NonNull RecyclerView.ViewHolder viewHolder, int i) {
                int swipedPosition = viewHolder.getAdapterPosition();
                Adapter adapter = (Adapter) mRecyclerView.getAdapter();
                //If you want to register, the process of deleting from the list is here
                //Notify that it has been deleted and reflect it.
                adapter.notifyItemRemoved(swipedPosition);
            }

            @Override
            public void onChildDraw (@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                View itemView = viewHolder.itemView;

                //When canceled
                if (dX == 0f && !isCurrentlyActive) {
                    clearCanvas(c, itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
                    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, false);
                    return;
                }

                ColorDrawable background = new ColorDrawable();
                background .setColor(Color.parseColor("#f44336"));
                background.setBounds(itemView.getRight() + (int)dX, itemView.getTop(),  itemView.getRight(), itemView.getBottom());
                background.draw(c);

                int deleteIconTop = itemView.getTop() + (itemView.getHeight() - deleteIcon.getIntrinsicHeight()) / 2;
                int deleteIconMargin = (itemView.getHeight() - deleteIcon.getIntrinsicHeight()) / 2;
                int deleteIconLeft = itemView.getRight() - deleteIconMargin - deleteIcon.getIntrinsicWidth();
                int deleteIconRight = itemView.getRight() - deleteIconMargin;
                int deleteIconBottom = deleteIconTop +  deleteIcon.getIntrinsicHeight();

                deleteIcon.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom);
                deleteIcon.draw(c);
            }
        };
        new ItemTouchHelper(callback).attachToRecyclerView(mRecyclerView);

    }

    private void clearCanvas(Canvas c, int left, int top, int right, int bottom) {
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        c.drawRect(left, top, right, bottom, paint);
    }
    //abridgement...

Icon images, calculations, color codes, and processing ideas are "Swipe to delete the Android list # How do you do that?" By @ shts And from that Github. I'm sorry without permission.

It is ʻonSwiped`` that fires when the swipe is completed, but even if you cancel it, ʻonChildDraw is called every frame on the way. It seems that ```onMove is for when drag and drop is also allowed, but should I return false?

As an additional note, it seems that you can allow both right swipe and left swipe as follows.

        ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

            @Override
            public boolean onMove (@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
                return false;
            }

            @Override
            public void onSwiped (@NonNull RecyclerView.ViewHolder viewHolder, int i) {
                
            }

            @Override
            public void onChildDraw (@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                if (dX < 0) {
                    //When swiping left
                } else {
                    //When swiping right
                }
            }
        };

It's hidden and you can't see it at first glance, but be careful because it says ʻItemTouchHelper.LEFT | ItemTouchHelper.RIGHT`` at the end of the first line. ʻonChildDraw is as above, but I don't know how to divide the processing in` ʻonSwiped. (Do you use `ʻi``?)

5. Summary

First of all, thank you to the posters of the site for your reference. It's a little rough, but I'll introduce it here.

Basics of RecyclerView I tried to imitate the RecyclerView itself in almost the same way.

Drag and drop move and swipe removal in RecyclerView I got the image of a swipe.

Swipe to delete the list on Android #How do you do that? I have rewritten the swipe process in Java. → Images and detailed processing are from the attached GitHub.

Note on how to delete an element with a horizontal swipe using RecyclerView on Android I referred to how to update Adapter in Java.

How to delete items in RecyclerView by swiping I referred to the additional processing outside the post.

Thank you everyone. I'm sorry that I can only create processing by wrapping around other people's code in this way, but that's why I hope to benefit someone.

Twitter: https://twitter.com/Cyber_Hacnosuke (Please follow me.) Please like it too.

Recommended Posts

[Java] Note how to use RecyclerView and implementation of animated swipe processing.
[Processing × Java] How to use arrays
[Processing × Java] How to use the loop
[Java] [Maven3] Summary of how to use Maven3
[Processing × Java] How to use the class
How to use Java Scanner class (Note)
[Processing × Java] How to use the function
[Java] How to use FileReader class and BufferedReader class
How to use Segmented Control and points to note
How to use scope and pass processing (Jakarta)
[Java] How to use Calendar class and Date class
[Java] How to use compareTo method of Date class
Summary of Java communication API (1) How to use Socket
Summary of Java communication API (3) How to use SocketChannel
Summary of Java communication API (2) How to use HttpUrlConnection
[Java] How to use Map
How to use java Optional
How to use java class
[Java] How to use Optional ②
[Java] How to use removeAll ()
[Java] How to use string.format
How to use Java Map
How to use Java variables
[Java] How to use Optional ①
How to use trained model of tensorflow2.0 with Kotlin / Java
[Processing × Java] How to use loop 2 --- Nested structure, coordinate conversion
How to call and use API in Java (Spring Boot)
How to use StringBurrer and Arrays.toString.
How to use Java HttpClient (Get)
[Rails] How to use devise (Note)
How to use EventBus3 and ThreadMode
How to use Java HttpClient (Post)
[Java] How to use join method
How to use equality and equality (how to use equals)
How to use setDefaultCloseOperation () of JFrame
[Java] How to use LinkedHashMap class
[JavaFX] [Java8] How to use GridPane
How to use class methods [Java]
[Java] How to use List [ArrayList]
How to use classes in Java?
How to use Java lambda expressions
[Java] How to use Math class
How to use Java enum type
Basics of Java development ~ How to write programs (variables and types) ~
[Java] How to use static modifiers (What are static final and static import)
How to write offline real-time Java implementation example of F01 problem
Multilingual Locale in Java How to use Locale
[Java] How to use the File class
[Java] How to use the hasNext function
[java] Summary of how to handle char
How to use submit method (Java Silver)
[Easy-to-understand explanation! ] How to use Java instance
[Java] How to use the toString () method
Java implementation to create and solve mazes
[Java] How to output and write files!
How to set up and use kapt
How to use Java classes, definitions, import
[Note] How to use Rails 6 Devise + cancancan
[Easy-to-understand explanation! ] How to use ArrayList [Java]
How to use substring and substr methods
[Java] How to use the Calendar class