본문 바로가기

안드로이드/코드

[안드로이드] 리싸이클러뷰 아이템 이동, 삭제 - RecyclerView, ItemTouchHelper

반응형

 

 

 

 

리싸이클러뷰2_1

 

ItemTouchHelper를 이용해서 리싸이클러뷰의 아이템 이동, 삭제 이벤트 예제를 만들어보겠습니다.

-롱클릭 후 위아래로 움직이면 순서 변경

-아이템을 왼쪽이나 오른쪽으로 스와이프하면 삭제

 

리싸이클러뷰의 기본 예제가 궁금하시면 링크를 클릭하세요

 

 

 

 

1. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:layout_marginTop="10dp"
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>



</LinearLayout>

 

2. list_item.xml (리싸이클러뷰 아이템의 뷰)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:orientation="horizontal">
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cardBackgroundColor="#FFFFFF"
        app:cardUseCompatPadding="true">

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

            <ImageView
                android:id="@+id/list_image"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:padding="5dp"
                app:srcCompat="@mipmap/ic_launcher" />

            <TableLayout
                android:gravity="center"
                android:stretchColumns="1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1">

                <TableRow>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="left"
                        android:layout_marginLeft="10dp"
                        android:textColor="@android:color/black"
                        android:text="이름"
                        android:textSize="20sp" />

                    <TextView
                        android:id="@+id/list_name"
                        android:textColor="@android:color/black"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textSize="20sp" />

                </TableRow>


                <TableRow>

                    <TextView
                        android:textColor="@android:color/black"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="left"
                        android:layout_marginLeft="10dp"
                        android:text="나이"
                        android:textSize="20sp" />

                    <TextView
                        android:id="@+id/list_age"
                        android:textColor="@android:color/black"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textSize="20sp" />
                </TableRow>


            </TableLayout>


        </LinearLayout>

    </androidx.cardview.widget.CardView>



</FrameLayout>

 

 

3. Person.java (데이터를 저장할 객체)

public class Person {
    int image;
    String name;
    int age;

    public Person(int image, String name, int age){
        this.image = image;
        this.name = name;
        this.age = age;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

 

4. ItemTouchHelperListener.interface (인터페이스로 만들어주세요)

public interface ItemTouchHelperListener {
    boolean onItemMove(int from_position, int to_position);
    void onItemSwipe(int position);
}

 

 

5. ItemTouchHelperCallback

package com.everyshare.recyclerviewtest;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private ItemTouchHelperListener listener;

    public ItemTouchHelperCallback(ItemTouchHelperListener listener) {
        this.listener = listener;
    }


    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        int drag_flags = ItemTouchHelper.UP|ItemTouchHelper.DOWN;
        int swipe_flags = ItemTouchHelper.START|ItemTouchHelper.END;
        return makeMovementFlags(drag_flags,swipe_flags);
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {

        return listener.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        listener.onItemSwipe(viewHolder.getAdapterPosition());
    }
}

 

 

참고하실 부분은 onMove와 onSwipe중 하나만 사용하겠다라고 하신다면 

getMovementFlags에서 return을 해주는 makeMovementFlags함수의 인자로 0을 넣어주시면 됩니다.

예를 들면, 

onMove만 사용(onSwipe 사용안함) - return makeMovementFlags(drag_flags,0);

onSwipe만 사용(onMove 사용안함) - return makeMovementFlags(0,swipe_flags);

 

6.ListAdapter.java (리싸이클러뷰의 CustomAdapter)

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ItemViewHolder>
            implements ItemTouchHelperListener{

    ArrayList<Person> items = new ArrayList<>();

    public ListAdapter(){
    }


    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //LayoutInflater를 이용해서 원하는 레이아웃을 띄워줌
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.list_item, parent, false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
        //ItemViewHolder가 생성되고 넣어야할 코드들을 넣어준다.
        holder.onBind(items.get(position));
    }

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

    public void addItem(Person person){
        items.add(person);
    }



    @Override
    public boolean onItemMove(int from_position, int to_position) {
        //이동할 객체 저장
        Person person = items.get(from_position);
        //이동할 객체 삭제
        items.remove(from_position);
        //이동하고 싶은 position에 추가
        items.add(to_position,person);

        //Adapter에 데이터 이동알림
        notifyItemMoved(from_position,to_position);
        return true;
    }

    @Override
    public void onItemSwipe(int position) {
        items.remove(position);
        notifyItemRemoved(position);
    }

    class ItemViewHolder extends RecyclerView.ViewHolder {

        TextView list_name,list_age;
        ImageView list_image;



        public ItemViewHolder(View itemView) {
            super(itemView);
            list_name = itemView.findViewById(R.id.list_name);
            list_age = itemView.findViewById(R.id.list_age);
            list_image = itemView.findViewById(R.id.list_image);
        }

        public void onBind(Person person) {
            list_name.setText(person.getName());
            list_age.setText(String.valueOf(person.getAge()));
            list_image.setImageResource(person.getImage());
        }
    }
}

onItemMove, onItemSwipe가 ItemTouchHelper를 이용한 이벤트를 발생시키는 함수입니다.

 

7. MainActivity.java

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class MainActivity extends AppCompatActivity {
    RecyclerView rv;
    ListAdapter adapter;
    ItemTouchHelper helper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);





        rv = findViewById(R.id.rv);
        //RecyclerView의 레이아웃 방식을 지정
        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        rv.setLayoutManager(manager);

        //RecyclerView의 Adapter 세팅
        adapter = new ListAdapter();
        rv.setAdapter(adapter);
        
        //ItemTouchHelper 생성
        helper = new ItemTouchHelper(new ItemTouchHelperCallback(adapter));
        //RecyclerView에 ItemTouchHelper 붙이기
        helper.attachToRecyclerView(rv);
        
        
        //Adapter에 데이터 추가
        Person person1 = new Person(R.drawable.image1,"파이리",1);
        Person person2 = new Person(R.drawable.image2,"피카츄",2);
        Person person3 = new Person(R.drawable.image3,"꼬부기",3);
        Person person4 = new Person(R.drawable.image4,"이상해씨",4);
        adapter.addItem(person1);
        adapter.addItem(person2);
        adapter.addItem(person3);
        adapter.addItem(person4);
    }
}

 

다음 포스팅에서는 아이템의 정보를 수정하고 초기화하는 예제를 만들어보겠습니다.

반응형