来自同一个类的ViewHolder扩展有不同的视图类型(两个不同的ViewHolders具有相同的稳定ID)

时间:2020-12-12 20:55:38

There is only one ViewHolder class in my RecyclerView adapter:

只有一个ViewHolder类在我的回收视图适配器中:

public static class PlayerItemViewHolder extends RecyclerView.ViewHolder {
    public ImageView news_image;
    public TextView news_title;
    public PlayerItemViewHolder(View view) {
        super(view);
        news_image = (ImageView) view.findViewById(R.id.news_image);
        news_title = (TextView) view.findViewById(R.id.news_title);
    }
}

@Override
public PlayerAdapter.PlayerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View item_view = layoutInflater.inflate(R.layout.player_news_item, parent, false);
    return new PlayerItemViewHolder(item_view);
}
 @Override
public void onBindViewHolder(final PlayerAdapter.PlayerItemViewHolder viewHolder, Cursor cursor) {
    Log.d("id", viewHolder.getItemId()+"");
    Log.d("view_type", viewHolder.getItemViewType()+"");
    Log.d("class", viewHolder.getClass().toString());
}

When I run this code:

当我运行这段代码:

08-27 15:57:03.414 19971-19971/? D/id: 0
08-27 15:57:03.414 19971-19971/? D/view_type: 1
08-27 15:57:03.414 19971-19971/? D/class: class io.github.nekotachi.easynews.ui.adapter.PlayerAdapter$PlayerItemViewHolder
08-27 15:57:03.421 19971-19971/? D/id: 0
08-27 15:57:03.421 19971-19971/? D/view_type: 2
08-27 15:57:03.421 19971-19971/? D/class: class io.github.nekotachi.easynews.ui.adapter.PlayerAdapter$PlayerItemViewHolder

Finally, it causes the error:

最后,它导致了错误:

java.lang.IllegalStateException: Two different ViewHolders have the same stable ID. Stable IDs in your adapter MUST BE unique and SHOULD NOT change.

In this case, I think the view type should be same because they have same class. And also, the id should be different too.

在这种情况下,我认为视图类型应该相同,因为它们有相同的类。而且,id也应该是不同的。

1 个解决方案

#1


1  

I guess you're passing different ViewType for your views in the RecyclerView from getItemViewType function.

我猜您是通过getItemViewType函数的回收视图传递不同的视图类型。

If you're returning different ViewType from getItemViewType then you need to handle the ViewType differently inside your onBindViewHolder along with having different ViewHolder types too.

如果您从getItemViewType返回不同的ViewType,那么您需要在onBindViewHolder中以不同的方式处理ViewType,以及使用不同的ViewHolder类型。

For example, you've two different ViewType. This two can have same layout. But you need to specify a ViewHolder for each of them like this.

例如,您有两种不同的视图类型。这两个可以有相同的布局。但是你需要指定一个ViewHolder,像这样。

// For view_type = 1
private class FirstItemViewHolder extends ViewHolder {
    public FirstItemViewHolder(View itemView) {
        super(itemView);
    }
}

// For view_type = 2
private class SecondItemViewHolder extends ViewHolder {
    public SecondItemViewHolder(View itemView) {
        super(itemView);
    }
}

Now from your getItemViewType method you're returning the ViewType as usual.

现在,从getItemViewType方法,您将像往常一样返回ViewType。

@Override
public int getItemViewType(int position) {
    if(returnFirstViewType()){
        return VIEW_TYPE_1;
    } else {
        return VIEW_TYPE_2;
    }

    return super.getItemViewType(position);
}

Now when you are binding each view holder in your onBindViewHolder method, you need to check the ViewType first and then you need to take the other actions like this.

现在,当您在onBindViewHolder方法中绑定每个视图holder时,您需要首先检查ViewType,然后您需要采取像这样的其他操作。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    try {
        if (holder instanceof FirstItemViewHolder) {
            FirstItemViewHolder vh = (FirstItemViewHolder) holder;
            // Code for view_type = 1 goes here

        } else {
            // Code for view_type = 2 goes here
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

#1


1  

I guess you're passing different ViewType for your views in the RecyclerView from getItemViewType function.

我猜您是通过getItemViewType函数的回收视图传递不同的视图类型。

If you're returning different ViewType from getItemViewType then you need to handle the ViewType differently inside your onBindViewHolder along with having different ViewHolder types too.

如果您从getItemViewType返回不同的ViewType,那么您需要在onBindViewHolder中以不同的方式处理ViewType,以及使用不同的ViewHolder类型。

For example, you've two different ViewType. This two can have same layout. But you need to specify a ViewHolder for each of them like this.

例如,您有两种不同的视图类型。这两个可以有相同的布局。但是你需要指定一个ViewHolder,像这样。

// For view_type = 1
private class FirstItemViewHolder extends ViewHolder {
    public FirstItemViewHolder(View itemView) {
        super(itemView);
    }
}

// For view_type = 2
private class SecondItemViewHolder extends ViewHolder {
    public SecondItemViewHolder(View itemView) {
        super(itemView);
    }
}

Now from your getItemViewType method you're returning the ViewType as usual.

现在,从getItemViewType方法,您将像往常一样返回ViewType。

@Override
public int getItemViewType(int position) {
    if(returnFirstViewType()){
        return VIEW_TYPE_1;
    } else {
        return VIEW_TYPE_2;
    }

    return super.getItemViewType(position);
}

Now when you are binding each view holder in your onBindViewHolder method, you need to check the ViewType first and then you need to take the other actions like this.

现在,当您在onBindViewHolder方法中绑定每个视图holder时,您需要首先检查ViewType,然后您需要采取像这样的其他操作。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    try {
        if (holder instanceof FirstItemViewHolder) {
            FirstItemViewHolder vh = (FirstItemViewHolder) holder;
            // Code for view_type = 1 goes here

        } else {
            // Code for view_type = 2 goes here
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}