为什么在重写 getItemViewType() 后,带有 ItemTouchHelper 的 RecyclerView 仅在一项之后停止拖动?

2024-02-05

我有一个简单的 RecyclerView,它使用 ItemTouchHelper 来滑动和拖动项目。一切工作正常,直到我需要以不同的方式设置第一个和最后一个项目的样式,因此我需要重写适配器中的 getItemViewType(int p) 函数。在我这样做之后,拖动功能不再流畅,并且总是在仅向上/向下移动一个位置后丢弃项目。这是我的 RecyclerView 适配器:

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:

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 上的覆盖并对所有项目使用相同的布局,则一切正常,但我非常希望找到此问题的解决方案。任何帮助将非常感激 :)


适配器认为两者ViewHolder你搬家已被视为不同类型因为getItemViewType()返回唯一的类型。所以应该重新渲染。

例如,您可以按照我的过程返回类型:

return 0对于 r.layout.foo

return 1对于 r.layout.bar

然后你可以编写自己的方法/对来检查布局您想要按类型进行布局。如果你仍然需要这个位置,之后就可以得到ViewHolder被建造:AdapterPosition.

如果您需要职位OnCreateViewHolder(),你有问题并且可能违背了目的ViewHolder。考虑在操作数据时或在onBindViewHolder()如果不是那么贵的话。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在重写 getItemViewType() 后,带有 ItemTouchHelper 的 RecyclerView 仅在一项之后停止拖动? 的相关文章

随机推荐