안 드 로 이 드 ItemTouchHelper 는 드래그 와 옆으로 미 끄 러 질 수 있 는 목록 의 예제 코드 를 실현 합 니 다.

머리말
할 말 이 많 지 않 으 니 바로 그림 을 올 려 라.

필 자 는 RecyclerView 의 ItemTouchHelper 를 사용 하여 이 효 과 를 실현 하 는데 과정 이 매우 간단 하 다.공 부 를 위해 사 이 드 스 케 이 트 삭 제 를 실현 했다.
구현 기능:
  • 아 이 템 왼쪽 버튼 을 누 르 면 아 이 템 을 위아래 로 끌 수 있 습 니 다
  • 오른쪽으로 미 끄 러 짐 삭제 item
  • item 드래그 하거나 옆으로 미 끄 러 질 때 그림자 효과 가 있 습 니 다
  • 기본 기능 을 실현 하 다
    순서에 따라 점진 적 으로 학습 하면 여기 서 우 리 는 먼저 기본 적 인 기능 을 실현 한다.
    4
  • 아 이 템 에 따라 상하 드래그 를 실현 합 니 다
  • 오른쪽으로 미 끄 러 짐 삭제레이아웃 파일
    간단 합 니 다.더 말 하지 않 고 코드 를 직접 올 립 니 다.
    activity_main.xml
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    
      <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/main_recyclerView"
        android:scrollbars="none"
        android:background="#F2F8FC">
      </android.support.v7.widget.RecyclerView>
    
    </LinearLayout>
    
    
    item_list.xml
    
    <?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"
      android:layout_width="match_parent"
      android:layout_height="60dp"
      android:background="#ffffff">
      
      <ImageView
        android:id="@+id/item_list_menu_imageView"
        android:layout_width="30dp"
        android:layout_height="25dp"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="15dp"
        android:layout_marginTop="8dp"
        android:src="@drawable/imageview_menu"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
      
      <TextView
        android:id="@+id/item_list_text_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="15dp"
        android:layout_marginTop="8dp"
        android:textColor="#000000"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/item_list_menu_imageView"
        app:layout_constraintTop_toTopOf="parent"/>
    
      <android.support.v7.widget.SwitchCompat
        android:id="@+id/item_list_switchCompat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="15dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
      
    </android.support.constraint.ConstraintLayout>
    
    
    ItemTouchHelper
    공식 API 설명:
    This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
    이것 은 RecyclerView 에 사 이 드 슬라이딩 삭제 와 드래그 를 추가 하 는 도구 클래스 입 니 다.그것 이 있 으 면 우 리 는 위의 효 과 를 편리 하 게 실현 할 수 있다.구조 기:ItemTouchHelper(ItemTouchHelper.Callback callback)를 통 해 알 수 있 듯 이 우 리 는 ItemTouchHelper.Callback 으로 ItemTouchHelper 를 구성 해 야 합 니 다.
    ItemTouchHelper.Callback 은 공식 적 으로 ItemTouchHelper.Simple Callback()을 제공 합 니 다.사용 은 간단 하지만 더 높 은 맞 춤 형 제작 성 을 얻 기 위해 서 는 사용 하지 않 습 니 다.관심 있 는 친구 들 이 시도 해 보 세 요.
    새로 만 든 MyItemTouchHelperCallback 클래스 는 ItemTouchHelper.Callback 을 계승 합 니 다.여기 서 우 리 는 그 중의 세 가지 방법 을 주목 합 니 다.
  • getMovement Flags()는 item 의 끌 고 미 끄 러 질 수 있 는 방향 을 정의 합 니 다
  • onMove()아 이 템 이 위아래 로 끌 려 고 할 때 이 방법 을 사용 합 니 다
  • onSwiped 는 item 이 좌우 로 미 끄 러 지 려 고 할 때 이 방법 을 사용 합 니 다
  • MyItemTouchHelperCallback 을 쓰기 전에 이 인 터 페 이 스 를 실현 할 수 있 도록 IItemTouchHelperAdapter 인 터 페 이 스 를 만 듭 니 다.RecyclerView Adapter 리 셋 에 사용 합 니 다.
    
    public interface IItemTouchHelperAdapter {
      /**
       *  item      
       *
       * @param fromPosition     item   
       * @param toPosition      item   
       */
      void onItemMove(int fromPosition, int toPosition);
    
      /**
       *  item      
       *
       * @param position     item position
       */
      void onItemDismiss(int position);
    }
    
    
    RecyclerView Adapter 에서 방금 계승 한 두 가지 방법 을 실현 합 니 다.
    
     @Override
      public void onItemMove(int fromPosition, int toPosition) {
        Collections.swap(mList, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
      }
    
      @Override
      public void onItemDismiss(int position) {
        mList.remove(position);
        notifyItemRemoved(position);
      }
    
    
    그 후에 우 리 는 MyItemTouchHelper Callback 을 작성 할 수 있 습 니 다.주석 이 명확 하고 더 이상 말 하지 않 겠 습 니 다.
    
    public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
    
      private IItemTouchHelperAdapter mAdapter;
    
      public MyItemTouchHelperCallback(IItemTouchHelperAdapter mAdapter) {
        this.mAdapter = mAdapter;
      }
    
      @Override
      public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //    ,        
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //    ,        
        int swipeFlags = ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags, swipeFlags);
      }
    
      @Override
      public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        //  Adapter       
        mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        //   false          
        return true;
      }
    
      @Override
      public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        //  Adapter       
        mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
      }
      
      @Override
      public boolean isItemViewSwipeEnabled() {
        //        ,    true
        return true;
      }
    
      @Override
      public boolean isLongPressDragEnabled() {
        //          ,    false
        return true;
      }
    }
    
    
    마지막 으로 Acivity 에서 ItemTouchHelper 와 RecyclerView 를 연결 합 니 다.
    
    mItemTouchHelper = new ItemTouchHelper(new MyItemTouchHelperCallback(adapter));
    mItemTouchHelper.attachToRecyclerView(recyclerView);
    실행 효과:

    완벽 하 다.
    우리 가 실현 하 는 기본 적 인 효 과 는 글 의 시작 부분 에서 제시 한 효과 와 약간의 차이 가 있 고 실현 해 야 할 효과 도 있다.
    4.567917.item 왼쪽 단 추 를 눌 러 야 위아래 로 끌 수 있 습 니 다
  • 옆으로 미 끄 러 지 거나 끌 어 당 길 때 작 동 하 는 item Z 축 높이 가 증가 하여 뚜렷 한 그림자 가 있 습 니 다
  • 아 이 템 왼쪽 단 추 를 눌 러 야 위아래 로 끌 수 있 습 니 다.
    먼저 MyItemTouchHelperCallback 의 isLongPressDragEnabled()를 수정 합 니 다.
     
    
    @Override
      public boolean isLongPressDragEnabled() {
        //    item      ,               
        return false;
      }
    
    그 다음 에 OnStart DragListener 인 터 페 이 스 를 새로 만 들 고 리 셋 에 사용 합 니 다.
    
    public interface OnStartDragListener {
      /**
       *  View       
       *
       * @param viewHolder The holder of view to drag
       */
      void onStartDrag(RecyclerView.ViewHolder viewHolder);
    }
    
    Activity 에 이 종 류 를 계승 하여 onStartDrag()방법 을 실현 합 니 다.
    
    @Override
      public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
        //  ItemTouchHelper    
        mItemTouchHelper.startDrag(viewHolder);
      }
    
    RecyclerView Adapter 의 구조 방법 에 OnStart DragListener 의 인 스 턴 스(즉,이 인터페이스의 Activity 구현)를 전송 하여 item 왼쪽 단추 에 이벤트 감청 을 추가 합 니 다.
    
    public class RecyclerViewAdapter extends
        RecyclerView.Adapter<RecyclerViewAdapter.IItemViewHolder> implements IItemTouchHelperAdapter {
      //    
      public RecyclerViewAdapter(List<ItemEntity> list, OnStartDragListener mDragListener) {
        mList = list;
        this.mDragListener = mDragListener;
      }
      
      ...
      
       @Override
      public void onBindViewHolder(final IItemViewHolder holder, @SuppressLint("RecyclerView") final int position) {
        ...
        holder.menu.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction()
                == MotionEvent.ACTION_DOWN) {
              //  ItemTouchHelper      
              mDragListener.onStartDrag(holder);
            }
            return false;
          }
        });
      }
      
      ...
    }
    
    옆으로 미 끄 러 지 거나 끌 어 당 길 때 작 동 하 는 아 이 템 Z 축의 높이 가 증가 하여 뚜렷 한 음영 이 있 음
    이 효 과 를 실현 하려 면 필 자 는 ItemTouchHelper.Callback 이 제공 하 는 두 가지 반전 방법 을 사용한다.
  • onSelected Changed(RecyclerView.ViewHolder viewHolder,int actionState):ViewHolder(즉 item)가 미 끄 러 지 거나 끌 릴 때 호출 됩 니 다
  • clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder):ViewHolder 의 미끄럼 과 드래그 가 끝 날 때 호출 됩 니 다
  • 우선 IItemTouchHelperViewHolder 인 터 페 이 스 를 새로 만 들 고 RecyclerViewAdapter 의 ViewHolder 를 계승 합 니 다.
    
    public interface IItemTouchHelperViewHolder {
    
      /**
       * item   ,             
       */
      void onItemSelected();
    
      /**
       * item        ,       
       */
      void onItemClear();
    }
    
    
    그리고 View Holder 에 게 상기 두 가지 방법 을 다시 쓰 게 합 니 다.
    
     class ItemViewHolder extends RecyclerView.ViewHolder implements IItemTouchHelperViewHolder {
        private TextView text;
        private ImageView menu;
        private SwitchCompat switchCompat;
    
        ItemViewHolder(View itemView) {
          super(itemView);
          text = itemView.findViewById(R.id.item_list_text_textView);
          menu = itemView.findViewById(R.id.item_list_menu_imageView);
          switchCompat = itemView.findViewById(R.id.item_list_switchCompat);
        }
    
        @Override
        public void onItemSelected() {
          itemView.setTranslationZ(10);
        }
    
        @Override
        public void onItemClear() {
          itemView.setTranslationZ(0);
        }
    }
    
    
    여기 서 setTranslationZ()를 통 해 itemView 의 높이 를 바 꿉 니 다.
    이전에 필 자 는 setElevation()을 통 해 높이 를 바 꾸 려 고 시 도 했 지만 통 하지 않 았 다.나중에 자 료 를 찾 아 보 니 View 의 Z 축 그림자 Z=elevation+translationZ 중:
  • elevation 은 정적 값 이 고 View 가 Z 축 에서 의 초기 값 입 니 다
  • translationZ 는 동적 값 이 고 Z 의 오프셋 변화 이다
  • 그래서 우 리 는 setTranslationZ()를 사용 하여 View 의 Z 축 높이 를 바 꾸 어야 한다.setElevation()을 사용 하 는 것 이 아니 라 독자 들 이 스스로 시도 해 볼 수 있다.
    마지막 으로 MyItemTouchHelperCallback 을 수정 하고 상기 두 가지 방법 을 다시 작성 합 니 다.과정 은 간단 합 니 다.코드 를 직접 보 세 요.
    
     @Override
      public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
          //      ,         
          if (viewHolder instanceof IItemTouchHelperViewHolder) {
            IItemTouchHelperViewHolder itemTouchHelperViewHolder =
                (IItemTouchHelperViewHolder) viewHolder;
            itemTouchHelperViewHolder.onItemSelected();
          }
        }
        super.onSelectedChanged(viewHolder, actionState);
      }
    
      @Override
      public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        if (viewHolder instanceof IItemTouchHelperViewHolder) {
          IItemTouchHelperViewHolder itemTouchHelperViewHolder =
              (IItemTouchHelperViewHolder) viewHolder;
          itemTouchHelperViewHolder.onItemClear();
        }
      }
    
    
    마지막.
    여 기 는[소스 코드]
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기