为什么在覆盖getItemViewType()之后,带有ItemTouchHelper的RecyclerView只停止拖动一个项目? [英] Why does my RecyclerView with ItemTouchHelper stop dragging after only one item, after overriding getItemViewType()?

查看:228
本文介绍了为什么在覆盖getItemViewType()之后,带有ItemTouchHelper的RecyclerView只停止拖动一个项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的RecyclerView,它使用ItemTouchHelper来滑动和拖动项目.在我需要对第一个和最后一个项目进行不同样式设置之前,一切工作正常,因此我需要重写适配器中的getItemViewType(int p)函数.完成后,拖动功能不再流畅,只能在上/下移动一个位置后才放下物品.这是我的RecyclerView适配器:

I have a simple RecyclerView that uses ItemTouchHelper to both swipe and drag items. Everything worked fine until I needed to style the first and last items differently, so I needed to override the getItemViewType(int p) function in the adapter. After I did, the drag functionality stopped being fluent and always dropped the items after moving only one position up/down. This is my RecyclerView Adapter:

public class CurrentStopsAdapter extends RecyclerView.Adapter<CurrentStopsAdapter.ViewHolder> {
private RemoveFromTripListener removeFromTripListener = null;
private SwapPlacesTripListener swapPlacesTripListener = null;
private Context context;
private List<PlaceLink> stops;

public CurrentStopsAdapter(Context context, List<PlaceLink> stops,
                           RemoveFromTripListener removeListener, SwapPlacesTripListener swapListener) {
    this.context = context;
    this.stops = stops;
    removeFromTripListener = removeListener;
    swapPlacesTripListener = swapListener;
}

public interface RemoveFromTripListener {
    void onRemoveTripButtonClick(String id);
}

public interface SwapPlacesTripListener {
    void onSwapPlacesButtonClick(int first, int second);
}

@Override
public int getItemViewType(int position) {
    if (position == (getItemCount()-1)) {
        return -1;
    }
    return position;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
        case -1:
            return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_destination, parent, false));
        case 0:
            return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_origin, parent, false));
        default:
            return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_stop, parent, false));
    }
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bindStop(stops.get(position));
}

@Override
public int getItemCount() {
    return stops.size();
}

public void remove(int position) {
    if (removeFromTripListener != null) {
        removeFromTripListener.onRemoveTripButtonClick(stops.get(position).getId());
    }
    notifyItemRemoved(position);
}

public void swap(int firstPosition, int secondPosition) {
    if (swapPlacesTripListener != null) {
       swapPlacesTripListener.onSwapPlacesButtonClick(firstPosition, secondPosition);
    }
    notifyItemMoved(firstPosition, secondPosition);
}

public class ViewHolder extends RecyclerView.ViewHolder {
    public final TextView placeTitle;

    public ViewHolder(View view){
        super(view);
        placeTitle = (TextView) view.findViewById(R.id.stops_list_item_title);
    }

    public void bindStop(PlaceLink place){
        this.placeTitle.setText(place.getTitle());

    }
}
}

和我的ItemTouchHelper:

And My ItemTouchHelper:

public class TripTouchHelper extends ItemTouchHelper.SimpleCallback {
    private CurrentStopsAdapter currentStopsAdapter;

    public TripTouchHelper(CurrentStopsAdapter currentStopsAdapter){
        super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
        this.currentStopsAdapter = currentStopsAdapter;
    }

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

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

}

如果我跳过getItemViewType上的Override并为所有项目使用相同的布局,则一切正常,但是我非常想找到解决此问题的方法.任何帮助将不胜感激:)

If I skip the Override on getItemViewType and use the same layout for all items, everything works fine but I would very much like to find a solutions to this problem. Any help would be really appreciated :)

推荐答案

适配器认为您移动的两个ViewHolder被视为不同类型,因为getItemViewType()返回的是唯一类型.因此,它应该重新渲染.

Adapter thinks that the both ViewHolder you moved is considered different type because getItemViewType() returned the type unique. So it should re-render.

例如,您可以按照我的步骤返回类型:

For example, you can return the type by following my procedure:

return 0表示r.layout.foo

return 0 for r.layout.foo

return 1用于r.layout.bar

return 1 for r.layout.bar

然后,您可以编写自己的方法/对,以在想要按类型排列布局时检查布局.如果您仍然需要该职位,则可以在创建ViewHolder之后获取该职位:AdapterPosition.

Then you can write own method/pair to check layout when you wanted the layout by type. If you still need the position, you can get it after ViewHolder is created:AdapterPosition.

如果您需要在OnCreateViewHolder()中的职位,则您有问题,可能无法达到ViewHolder的目的.在处理数据时或在onBindViewHolder()不太昂贵的情况下,考虑进行此工作.

If you needed position in OnCreateViewHolder(), you have something wrong and might defeated the purpose of ViewHolder. Considered doing that work when manipulating data or when onBindViewHolder() if not so expensive.

这篇关于为什么在覆盖getItemViewType()之后,带有ItemTouchHelper的RecyclerView只停止拖动一个项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆