Vô hiệu hóa Swipe cho vị trí trong RecyclerView bằng ItemTouchHelper.SimpleCallback


67
17
Võ Thanh Xuân
4 năm trước

Tôi đang sử dụng recyclerview 22.2.0 và lớp trình trợ giúp ItemTouchHelper.SimpleCallback để bật tùy chọn vuốt để loại bỏ vào danh sách của tôi. Nhưng khi tôi có một loại tiêu đề trên đó, tôi cần phải vô hiệu hóa hành vi vuốt cho vị trí đầu tiên của bộ chuyển đổi. RecyclerView.Ad CHƯƠNG không có phương thức isEnables () , tôi đã cố gắng vô hiệu hóa tương tác xem thông qua các phương thức isEnables ()isF Focusable () trong chính việc tạo ViewHolder, nhưng không thành công. Tôi đã cố gắng điều chỉnh ngưỡng vuốt thành giá trị đầy đủ, như 0f ot 1f trong phương thức của SimpleCallback getSwipeThr Ngưỡng () , nhưng cũng không thành công.

Một số đoạn mã của tôi để giúp bạn giúp tôi.

Hoạt động của tôi:

@Override
protected void onCreate(Bundle bundle) {
    //... initialization
    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0,
            ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

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

        @Override
        public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
            if (viewHolder instanceof CartAdapter.MyViewHolder) return 1f;
            return super.getSwipeThreshold(viewHolder);
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {

        }
    };

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);
}

Và tôi có một bộ chuyển đổi chung với hai loại xem. Trong ViewHolder mà tôi muốn tắt tính năng vuốt, tôi đã làm:

public static class MyViewHolder extends RecyclerView.ViewHolder {
    public ViewGroup mContainer;

    public MyViewHolder(View v) {
        super(v);
        v.setFocusable(false);
        v.setEnabled(false);
        mContainer = (ViewGroup) v.findViewById(R.id.container);      
    }
}
Hữu ích 67 Yêu thích 17 Chia sẻ Viết bình luận 0
Không hữu ích

6 Trả lời


149
Nguyễn Phi Nhung
4 năm trước

Sau khi chơi một chút, tôi đã quản lý SimpleCallback có một phương thức gọi là getSwipeDirs () . Vì tôi có một ViewHolder cụ thể cho vị trí không thể vuốt , tôi có thể sử dụng thể hiện để tránh thao tác vuốt. Nếu đó không phải là trường hợp của bạn, bạn có thể thực hiện điều khiển này bằng cách sử dụng vị trí của ViewHolder trong Bộ điều hợp.

@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    if (viewHolder instanceof CartAdapter.MyViewHolder) return 0;
    return super.getSwipeDirs(recyclerView, viewHolder);
}
Hữu ích 149 Trả lời hay nhất Chia sẻ Viết bình luận 5
Không hữu ích

Đáng nói hơn: nếu bạn muốn chỉ cho phép một hướng trên một số mặt hàng nhất định thì hãy sử dụng return position == 0 ? ItemTouchHelper.LEFT : super.getSwipeDirs(recyclerView, viewHolder);- hướng này tức là chỉ cho phép các thao tác vuốt trái.

Hữu ích 2 · Không hữu ích · Trả lời 0

Chính xác những gì tôi đang tìm kiếm! Đặc biệt là khi phương pháp này không xuất hiện trên tài liệu chính thức ...

Hữu ích 1 · Không hữu ích · Trả lời 0

@ptitvinou nó hiện diện trên SimpleCallback developer.android.com/intl/pt-br/reference/android/support/v7/

Hữu ích 1 · Không hữu ích · Trả lời 0

Hoàn hảo. Làm việc như một bùa mê

Hữu ích 0 · Không hữu ích · Trả lời 0

Cái này hoạt động ra sao? Tôi phải làm gì nếu tôi muốn tắt tính năng vuốt sang phải chẳng hạn?

Hữu ích 0 · Không hữu ích · Trả lời 0

58
Trần Mai Tâm
3 năm trước

Nếu ai đó đang sử dụng ItemTouchHelper.Callback . Sau đó, bạn có thể xóa mọi cờ liên quan trong hàm getMovementFlags (..) .

@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);
}

Tại đây thay vì dragFlagsswipeFlags Bạn có thể vượt qua 0 để tắt tính năng tương ứng.

ItemTouchHelper.START có nghĩa là vuốt từ trái sang phải trong trường hợp ngôn ngữ từ trái sang phải (Hỗ trợ ứng dụng LTR), nhưng cách khác là xoay quanh từ phải sang trái (Hỗ trợ ứng dụng RTL). ItemTouchHelper.END có nghĩa là vuốt theo hướng ngược lại START.

để bạn có thể loại bỏ bất kỳ cờ theo yêu cầu của bạn.

Hữu ích 58 Chia sẻ Viết bình luận 2
Không hữu ích

Cảm ơn !, Tôi sử dụng mã: @Override public int getMovementFlags (RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; // chuyển động kéo trở lại makeFlag (ItemTouchHelper.ACTION_STATE_DRAG, dragFlags); // làm tham số, kéo hành động và kéo cờ}

Hữu ích 0 · Không hữu ích · Trả lời 0

Đây là câu trả lời ưa thích nếu (không giống như OP) bạn đang gia hạn ItemTouchHelper.Callbacktrực tiếp.

Hữu ích 0 · Không hữu ích · Trả lời 0

18
Trần Tuấn Nghĩa
3 năm trước

Đây là một cách đơn giản để làm điều này chỉ phụ thuộc vào vị trí của vật phẩm được vuốt:

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder holder) {
    int position = holder.getAdapterPosition();
    int dragFlags = 0; // whatever your dragFlags need to be
    int swipeFlags = position == 0 ? 0 : ItemTouchHelper.START | ItemTouchHelper.END;

    return makeMovementFlags(dragFlags, swipeFlags);
}

Điều này cũng sẽ hoạt động nếu bạn đang sử dụng SimpleCallback:

@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder holder) {
    int position = holder.getAdapterPosition();
    return position == 0 ? 0 : super.getSwipeDirs(recyclerView, viewHolder);
}

Nếu bạn muốn tắt tính năng vuốt có điều kiện trên dữ liệu trong mục, hãy sử dụng positiongiá trị để lấy dữ liệu từ bộ điều hợp cho mục được vuốt và vô hiệu hóa tương ứng.

Nếu bạn đã có loại chủ sở hữu cụ thể không cần vuốt, câu trả lời được chấp nhận sẽ hoạt động. Tuy nhiên, việc tạo các loại chủ sở hữu như một proxy cho vị trí là một loại bùn và nên tránh.

Hữu ích 18 Chia sẻ Viết bình luận 0
Không hữu ích

5
Hoàng Quế Thu
3 năm trước

Có một vài cách để làm điều này, nhưng nếu bạn chỉ có một ViewHolder, nhưng nhiều hơn một bố cục, bạn có thể thực hiện phương pháp này.

Ghi đè getItemViewType và cung cấp cho nó một số logic để xác định kiểu xem dựa trên vị trí hoặc loại dữ liệu trong đối tượng (Tôi có hàm getType trong đối tượng của mình)

@Override
public int getItemViewType(int position) {
    return data.get(position).getType;
}

Trả về bố cục thích hợp trong onCreateView dựa trên ViewType (Đảm bảo chuyển loại dạng xem cho lớp ViewHolder.

@Override
public AppListItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    mContext = parent.getContext();

    if (viewType == 0){
        return new AppListItemHolder(LayoutInflater.from(mContext).inflate(R.layout.layout, parent, false), viewType);
    else
        return new AppListItemHolder(LayoutInflater.from(mContext).inflate(R.layout.header, parent, false), viewType);
    }
}

Nhận các khung nhìn nội dung của các bố cục khác nhau dựa trên loại khung nhìn công khai lớp tĩnh AppListItemHolder mở rộng RecyclerView.ViewHolder {

    public AppListItemHolder (View v, int viewType) {
        super(v);

        if (viewType == 0)
            ... get your views contents
        else
            ... get other views contents
        }
    }
}

Và sau đó trong ItemTouchHelper thay đổi hành động dựa trên ViewType. Đối với tôi điều này vô hiệu hóa việc vuốt tiêu đề phần RecyclerView

@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    if (viewHolder.getItemViewType() == 1) return 0;
        return super.getSwipeDirs(recyclerView, viewHolder);
    }
}
Hữu ích 5 Chia sẻ Viết bình luận 2
Không hữu ích

Ý tưởng tốt đẹp nhưng getItemViewType là cuối cùng

Hữu ích 0 · Không hữu ích · Trả lời 0

Đó là những gì tôi muốn, cảm ơn bạn

Hữu ích 0 · Không hữu ích · Trả lời 0

2
Lý Thùy Giang
1 năm trước

Đầu tiên trong recyclerView tại phương thức onCreateViewHolder, đặt thẻ cho từng loại viewHolder, như mã dưới đây:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    if(ITEM_TYPE_NORMAL == viewType) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.deposite_card_view, viewGroup, false);
        ItemViewHolder holder = new ItemViewHolder(context, v);
        holder.itemView.setTag("normal");
        return holder;
    } else {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_header, viewGroup, false);
        HeaderViewHolder holder = new HeaderViewHolder(context, v);
        holder.itemView.setTag("header");
        return holder;
    }
} 

sau đó trong triển khai ItemTouchHelper.Callback, cập nhật phương thức getMovementFlags, như bên dưới:

public class SwipeController extends ItemTouchHelper.Callback {

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    if("normal".equalsIgnoreCase((String) viewHolder.itemView.getTag())) {
        return makeMovementFlags(0, LEFT | RIGHT);
    } else {
        return 0;
    }
}

ở cuối đính kèm vào recyclerView:

final SwipeController swipeController = new SwipeController();

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController);
    itemTouchHelper.attachToRecyclerView(recyclerView);
Hữu ích 2 Chia sẻ Viết bình luận 0
Không hữu ích

1
Phan Kim Loan
1 năm trước

Ngoài câu trả lời @Rafael Toledo, Nếu bạn muốn xóa cử chỉ vuốt cụ thể như vuốt TRÁI hoặc vuốt PHẢI dựa trên vị trí hoặc loại dữ liệu trong đối tượng trong Bộ điều hợp, thì bạn có thể làm như thế này.

@Override
  public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
       {
          int position = viewHolder.getAdapterPosition();
          ConversationDataModel conversationModel = null;
          conversationModel = mHomeAdapter.getItems().get(position);
          boolean activeChat = true;
          if(conversationModel!=null && !conversationModel.isActive())
           {
             activeChat = false;
           }
  return activeChat ? super.getSwipeDirs(recyclerView, viewHolder): ItemTouchHelper.RIGHT;
        }

Ở đây trong trường hợp của tôi, trong Recyclerview của tôi, tôi đang tải các cuộc hội thoại trò chuyện và nó có các cử chỉ vuốt RIGHT (cho ARCHIVE) & LEFT (cho EXIT) trên mỗi mục. Nhưng trong trường hợp nếu cuộc hội thoại không hoạt động, thì tôi cần phải vô hiệu hóa thao tác vuốt PHẢI cho mục cụ thể trong chế độ xem Recycler.

Vì vậy, tôi đang kiểm tra activeChat và theo đó và vô hiệu hóa thao tác vuốt PHẢI.

Hy vọng nó sẽ giúp cho ai đó. "Chúc mừng !!

Hữu ích 1 Chia sẻ Viết bình luận 0
Không hữu ích

Trả lời của bạn

Xem trước nội dung