
RecyclerView의 item에 대해 좌우 swip을 하는 기능을 구현하는 방법에 대해 알아보았다.
해당 기능을 넣기 위해선 ItemTouchHelper.Callback()을 상속받는 클래스를 만들어 recyclerView와 연결시켜줘야한다.
ItemTouchHelper.Callback()을 상속받는 클래스를 만들면 다음과 같은 메소드들을 정의해줘야 한다.
public class TaskItemTouchHelperCallback extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
}
getMovementFlags에는 사용자가 item을 이동시킬 방향을 지정해줘야 한다.
onMove에는 item을 상하로 드래그할때의 이벤트를 정의해줘야 한다.
onSwiped에는 item을 좌우로 swipe할때의 이벤트를 정의해줘야 한다.
item의 swipe 이벤트를 구현하기 위해 ItemTouchHelper.Callback()을 상속받는 클래스 TaskItemTouchHelperCallback에 다음과 같이 코드를 작성했다.
public class TaskItemTouchHelperCallback extends ItemTouchHelper.Callback {
private OnItemSwipeListener listener;
public TaskItemTouchHelperCallback(OnItemSwipeListener listener){
this.listener = listener;
}
public interface OnItemSwipeListener{
void editItem(int position);
void removeItem(int position);
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int dragFlags = 0;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
if(direction == ItemTouchHelper.LEFT){
//EDIT
listener.editItem(viewHolder.getAdapterPosition());
}else if(direction == ItemTouchHelper.RIGHT){
//DELETE
listener.removeItem(viewHolder.getAdapterPosition());
}
}
// clearView after Swiped Event
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//super.clearView(recyclerView, viewHolder);
getDefaultUIUtil().clearView(viewHolder.itemView.findViewById(R.id.itemLayout));
}
}
getMovementFlags에는 좌우로의 swipe 기능을 구현하기 위해 ItemTouchHelper.LEFT와 ItemTouchHelper.RIGHT를 return 하도록 작성했다.
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int dragFlags = 0;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, swipeFlags);
}
드래그 기능은 구현하지 않기에 onMove에는 코드를 작성하지 않았다.
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
item의 swipe 이벤트를 구현하기 위해 onSwiped에는 다음과 같은 코드를 작성하였다.
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
if(direction == ItemTouchHelper.LEFT){
//EDIT
listener.editItem(viewHolder.getAdapterPosition());
}else if(direction == ItemTouchHelper.RIGHT){
//DELETE
listener.removeItem(viewHolder.getAdapterPosition());
}
}
이 때 각 방향으로 이동될 때 사용되는 메소드는 interface로 만들어 recyclerView가 사용되는 Activity에서 작성할 수 있도록 만들었다.
private OnItemSwipeListener listener;
public TaskItemTouchHelperCallback(OnItemSwipeListener listener){
this.listener = listener;
}
public interface OnItemSwipeListener{
void editItem(int position);
void removeItem(int position);
}
clearView 는 swipe 이벤트 후 아이템이 swipe 된 채로 남아있는 문제를 해결하기 위해 사용하였다.
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//super.clearView(recyclerView, viewHolder);
getDefaultUIUtil().clearView(viewHolder.itemView.findViewById(R.id.itemLayout));
}
recyclerView를 사용하는 Activity에서 다음과 같이 ItemTouchHelper.Callback()을 상속받는 클래스와 연결시킨다.
public class ListActivity extends AppCompatActivity implements TaskItemTouchHelperCallback.OnItemSwipeListener {
...
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TaskItemTouchHelperCallback(this));
itemTouchHelper.attachToRecyclerView(recyclerView);
...
// implements OnItemSwipeListener editItem
@Override
public void editItem(int position) {
Task task = adapter.getItem(position);
Intent intent = new Intent(getApplicationContext(), EditActivity.class);
intent.putExtra("id", task.getId());
intent.putExtra("task", task.getTask());
intent.putExtra("time", task.getTime());
editResultLauncher.launch(intent);
}
// implements OnItemSwipeListener removeItem
@Override
public void removeItem(int position) {
Task task = adapter.getItem(position);
String SQL = "DELETE FROM " + TABLE_NAME + " WHERE _id = " + task.getId();
TaskDatabase database = TaskDatabase.getInstance(this);
if(database != null){
database.execSQL(SQL);
loadTaskListData();
}
}
연결시킬 때 interface를 구현해 생성자의 인자로 전달해주었다.