垂直网格视图中的重复卡片

Posted

技术标签:

【中文标题】垂直网格视图中的重复卡片【英文标题】:Duplicated cards in verticalGridView 【发布时间】:2020-06-22 22:21:35 【问题描述】:

我有一个奇怪的问题。

上下文:

我正在构建一个使用 android 的 Leanback 库的 Android TV 应用程序。当用户导航到一个节目时,它有一个垂直网格视图,其中列出了该节目的所有剧集。

列表使用ArrayObjectAdapter 填充,我将列表中每一集的episodeModel 传递给该列表,然后我使用setAdapter(adapter) 将适配器设置为视图到目前为止一切顺利。

问题是当用户向下滚动列表时,在视口中不可见的项目会更新,但会更新已通过的项目的图像和标题。我的意思是,它们看起来像重复的项目,但真正发生的事情是最后的项目不会更新为自己的图像和标题,而是更新第一个项目。

如何防止这种情况发生?

这是 CardPresenter

public class CardPresenter extends Presenter 
    private static final String TAG = CardPresenter.class.getSimpleName();

    private static final int CARD_WIDTH = 420;
    private static final int CARD_HEIGHT= 236;
    private static int selectedBgColor;
    private static int defaultBgColor;
    private Drawable defaultCardimage;
    private ImageCardView mCardView;

    static class ViewHolder extends Presenter.ViewHolder
        ViewHolder(View view) 
            super(view);
        
    

    private static void updateCardBGColor(ImageCardView view, boolean selected)
        int color = selected ? selectedBgColor : defaultBgColor;
        view.setBackgroundColor(color);
        view.findViewById(R.id.info_field).setBackgroundColor(color);
    

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent) 
        defaultBgColor = ContextCompat.getColor(parent.getContext(), R.color.le_gray);
        selectedBgColor = ContextCompat.getColor(parent.getContext(), R.color.le_black);

        defaultCardimage = ContextCompat.getDrawable(parent.getContext(), R.drawable.default_bg);

        mCardView = new ImageCardView(parent.getContext()) 
            @Override
            public void setSelected(boolean selected) 
                super.setSelected(selected);
                updateCardBGColor(this, selected);
            
        ;
        mCardView.setMainImage(defaultCardimage);
        mCardView.setFocusable(true);
        mCardView.setFocusableInTouchMode(true);
        mCardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);

        return new ViewHolder(mCardView);
    

    @Override
    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) 
        if(item instanceof ShowModel)
            ShowModel showModel = (ShowModel) item;
            if(showModel.getThumbnail() != null)
                mCardView.setTitleText(showModel.getName());
                mCardView.setContentText(showModel.getType());
                mCardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
                Glide.with(viewHolder.view.getContext()).load(showModel.getThumbnail()).error(defaultCardimage).into(mCardView.getMainImageView());
            
        else if(item instanceof EpisodeModel)
            EpisodeModel episodeModel = (EpisodeModel) item;
            if(episodeModel.getStill() != null)
                mCardView.setTitleText(episodeModel.getTitle());
                mCardView.setContentText(episodeModel.getDescription());
                mCardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
                Glide.with(viewHolder.view.getContext()).load(episodeModel.getStill()).error(defaultCardimage).into(mCardView.getMainImageView());
            
        
    

    @Override
    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) 
        mCardView.setBadgeImage(null);
        mCardView.setMainImage(null);
    


【问题讨论】:

这听起来像是正在回收的视图的(重新)绑定问题。你能分享你在哪里设置标题、图像等的代码吗? 当然@IanG.Clifton,我刚刚更新了我的问题 【参考方案1】:

您需要更新 onBindViewHolder 才能使用 ViewHolder 更新视图。现在,您正在创建对最近创建的 ImageCardView 的引用,然后对其进行更新。例如,您有

mCardView.setTitleText(showModel.getName());

但 mCardView 不一定适合正确的位置。你需要做这样的事情:

viewHolder.itemView.setTitleText(showModel.getName());

您可能需要将 itemView 转换为 ImageCardView。

【讨论】:

以上是关于垂直网格视图中的重复卡片的主要内容,如果未能解决你的问题,请参考以下文章

尝试以编程方式使用嵌套的 Stack 视图制作网格

WPF 数据网格样式

如何清除数据网格视图

如何使 ViewPager 和 gridview 同时垂直滚动

CSS Grid没有填满整个视口[重复]

集合视图单元格垂直顶部对齐