Android

[개발일기] Recyclerview Item swipe & drag 막기

2018. 3. 8. 08:05


Recyclerview를 적용한 앱을 개발하는 중에 화면잠금기능으로 Recyclerview 아이템들이 선택되지 않아야하는 요구사항을 적용해야했다. 이것 저것 해봐도 안돼고 개발 초보인 나는 하루 반나절을 고민과 구글링한 끝에서야 답을 찾을 수 있었다.


RecyclerView에는 api22 부터 간편하게 swipe와 drag and drop item delete 를 할 수 있도록 ItemTouchHelper를 제공하기 때문에 이것을 이용해 swipe를 적용한다. 적용법은 매우 간단하다. 간단해서 반나절동안 찾은게 너무 아까웠다ㅠㅠ


일단 HelperCallback 클래스를 작성한다. 

public class ItemSwipeHelperCallback extends ItemTouchHelper.Callback {

    private final ItemTouchHelperAdapter mAdapter;

    public ItemSwipeHelperCallback(ItemTouchHelperAdapter adapter){
        mAdapter = adapter;
    }

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

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


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

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

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


}


swipe를 막을 수 있는 메소드가 있다.

바로 isLongPressDragEnabled()과 isItemViewSwipeEnabled()인데 각각 swipe했는지 여부와 drag의 사용여부를 알려주는 메소드다. true와 false를 통해 각각 기능을 끄고 켤 수 있는데, ItemTouchHelper 클래스에서 넘겨받아 swipe를 할지 안할지를 결정한다. 아래와 같이 세터를 만들어줘서 액티비티에서 필요할때마다 꺼내 끄고 키면된다.

 boolean mintem = true;

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

    @Override
    public boolean isItemViewSwipeEnabled() {
        return mintem;
    }

    public void setMintem(boolean mintem) {
        this.mintem = mintem;
    }


그 다음 Adapter interface를 작성해준다.

public interface ItemTouchHelperAdapter {
 
    void onItemMove(int fromPosition, int toPosition);
 
    void onItemDismiss(int position);
}

Recyclerview adapter에서 ItemTouchHelperAdapter를 implements하고 onItemMove와 OnItemDismiss를 오버라이딩해 swipe와 drag drop시 구현할 메소드 구현한다.


public class RecyclerViewAdapter extends
RecyclerView.Adapter<DreamViewAdapter.ViewHolder>
implements ItemTouchHelperAdapter {


마지막으로 target Recyclerview가 있는 activity에 붙여 주고 필요할때마다 callback.setMintem(t/f)로 사용여부를 정해주면된다.

ItemSwipeHelperCallback callback = new ItemSwipeHelperCallback(adapter);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(rv);


초급개발자로서 하나가 막힐 때 풀어 나가기가 너무 힘들다. 해결할때의 행복한 기분과 허탈함의 교차는 말을 할 수 없이 크다.

또 하나의 시련이 이렇게 지나가고 이또한 지나가리라 라는 마음으로 글을 작성한다.