recyclerview 22.2.0 및 도우미 클래스 ItemTouchHelper.SimpleCallback을 사용 하여 내 목록에 대해 스 와이프 하여 닫기 옵션을 활성화 합니다. 그러나 헤더 유형이 있으므로 어댑터의 첫 번째 위치에 대해 스 와이프 동작을 비활성화해야합니다. 으로 RecyclerView.Adapter이 없는 의 IsEnabled () 메소드를 나는 방법을 통해 뷰의 상호 작용을하지 않도록 노력 의 IsEnabled () 및 isFocusable () ViewHolder 생성 자체, 그러나 성공이 없었다. SimpleCallback의 메서드 getSwipeThreshold () 에서 0f ot 1f 와 같이 스 와이프 임계 값을 전체 값으로 조정하려고 했지만 성공하지 못했습니다.
당신이 나를 도울 수 있도록 내 코드의 일부.
내 활동 :
@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);
}
그리고 두 가지 보기 유형 이있는 공통 어댑터가 있습니다. 스 와이프를 비활성화하려는 ViewHolder 에서 다음을 수행 했습니다.
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);
}
}
답변
비트를 연주 후, 나는 그 관리 SimpleCallback이 방법이라고이 getSwipeDirs을 () . 스 와이프 할 수 없는 위치에 대한 특정 ViewHolder가 있으므로 스 와이프 를 방지하기 위해 instanceof 를 사용할 수 있습니다 . 그렇지 않은 경우 어댑터의 ViewHolder 위치를 사용하여이 제어를 수행 할 수 있습니다.
자바
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof CartAdapter.MyViewHolder) return 0;
return super.getSwipeDirs(recyclerView, viewHolder);
}
Kotlin
override fun getSwipeDirs (recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
if (viewHolder is CartAdapter.MyViewHolder) return 0
return super.getSwipeDirs(recyclerView, viewHolder)
}
답변
누군가 ItemTouchHelper.Callback을 사용하는 경우 . 그런 다음 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);
}
여기에서 dragFlags 및 swipeFlags 대신 0을 전달하여 해당 기능을 비활성화 할 수 있습니다.
ItemTouchHelper.START 는 왼쪽에서 오른쪽 로케일 (LTR 애플리케이션 지원)의 경우 왼쪽에서 오른쪽으로 스 와이프하지만 오른쪽에서 왼쪽 로케일 (RTL 애플리케이션 지원)에서는 반대 방향으로 스 와이프하는 것을 의미합니다.
ItemTouchHelper.END 는의 반대 방향으로 스 와이프하는 것을 의미 START
합니다.
따라서 요구 사항에 따라 플래그를 제거 할 수 있습니다.
답변
다음은 스 와이프되는 항목의 위치에만 의존하는 간단한 방법입니다.
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder holder) {
int position = holder.getAdapterPosition();
int dragFlags = 0; // whatever your dragFlags need to be
int swipeFlags = createSwipeFlags(position)
return makeMovementFlags(dragFlags, swipeFlags);
}
private int createSwipeFlags(int position) {
return position == 0 ? 0 : ItemTouchHelper.START | ItemTouchHelper.END;
}
다음을 사용하는 경우에도 작동합니다 SimpleCallback
.
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder holder) {
int position = holder.getAdapterPosition();
return createSwipeFlags(position);
}
private int createSwipeFlags(int position) {
return position == 0 ? 0 : super.getSwipeDirs(recyclerView, viewHolder);
}
항목의 데이터에 대한 조건부 스 와이프를 비활성화하려면 position
값을 사용하여 스 와이프되는 항목에 대한 어댑터에서 데이터를 가져오고 그에 따라 비활성화합니다.
스 와이프 할 필요가없는 특정 홀더 유형이 이미있는 경우 수락 된 답변이 작동합니다. 그러나 위치에 대한 프록시로 홀더 유형을 생성하는 것은 번거롭기 때문에 피해야합니다.
답변
이에 대해 몇 가지 방법이 있지만 ViewHolder가 하나만 있고 레이아웃이 둘 이상인 경우이 방법을 사용할 수 있습니다.
getItemViewType을 재정의하고 객체의 위치 또는 데이터 유형에 따라 뷰 유형을 결정하는 로직을 제공합니다 (객체에 getType 함수가 있습니다).
@Override
public int getItemViewType(int position) {
return data.get(position).getType;
}
ViewType을 기반으로 onCreateView에서 적절한 레이아웃을 반환합니다 (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);
}
}
보기 유형에 따라 다양한 레이아웃의 콘텐츠보기를 가져옵니다. public static class AppListItemHolder extends RecyclerView.ViewHolder {
public AppListItemHolder (View v, int viewType) {
super(v);
if (viewType == 0)
... get your views contents
else
... get other views contents
}
}
}
그런 다음 ItemTouchHelper에서 ViewType에 따라 작업을 변경합니다. 나를 위해 이것은 RecyclerView 섹션 헤더의 스 와이프를 비활성화합니다.
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder.getItemViewType() == 1) return 0;
return super.getSwipeDirs(recyclerView, viewHolder);
}
}
답변
먼저 onCreateViewHolder 메서드의 recyclerView에서 아래 코드와 같이 각 viewHolder 유형에 대한 태그를 설정합니다.
@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;
}
}
그런 다음 ItemTouchHelper.Callback 구현에서 아래와 같이 getMovementFlags 메서드를 업데이트합니다.
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;
}
}
끝에서 recyclerView에 연결 :
final SwipeController swipeController = new SwipeController();
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController);
itemTouchHelper.attachToRecyclerView(recyclerView);
답변
@Rafael Toledo 답변 외에도 Adapter에서 개체의 위치 또는 데이터 유형에 따라 LEFT 스 와이프 또는 RIGHT 스 와이프와 같은 특정 스 와이프 제스처를 제거하려면 다음과 같이 할 수 있습니다.
@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;
}
여기 내 경우 Recyclerview에서 채팅 대화를로드하고 있으며 각 항목에 대해 RIGHT (아카이브) 및 LEFT (EXIT) 스 와이프 제스처가 있습니다. 그러나 대화가 활성화되지 않은 경우 Recycler보기에서 특정 항목에 대해 오른쪽 스 와이프를 비활성화해야합니다.
그래서 나는 확인 activeChat
하고 그에 따라 오른쪽 스 와이프를 비활성화했습니다.
답변
다음을 사용하여 비활성화 할 수 있습니다. ItemTouchHelper.ACTION_STATE_IDLE
ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN, //drag directions
ItemTouchHelper.ACTION_STATE_IDLE //swipe directions
)
val touchHelperCallback = object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.ACTION_STATE_IDLE) {
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
(recyclerView.adapter as MyAdapter).onItemMove(viewHolder.adapterPosition, target.adapterPosition)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
return
}
}
val touchHelper = ItemTouchHelper(touchHelperCallback)
touchHelper.attachToRecyclerView(recyclerViewX)