当前位置: 首页 > 知识库问答 >
问题:

Android:recycle view滚动后内容混乱[关闭]

傅朗
2023-03-14

编辑问题以包括所需行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答这个问题。

我正在使用RecyclView显示标记列表,每个值的标记都显示为CardView。但是卡片的一些内容在向下滚动RecyclView并向后滚动后丢失,如下面的两个屏幕截图所示。滚动后红色矩形中的内容丢失。

我想知道这是否是RecyclizerView的一个错误,并且在谷歌搜索后找不到解决方案。

除标题外,所有视图均不可见,它们的可见性取决于标记的值。

有人知道为什么会这样吗?

共有3个答案

蒲曦
2023-03-14

onBindHolder调用了几次,因为除非是新视图,否则回收器视图需要一个视图。因此,每次在子视图中设置可见性时,其他视图状态也会发生变化。

每当您上下滚动时,这些视图都会使用错误的可见性选项重新绘制,因此请始终指定这两个条件,导致回收器视图不知道我们小部件的先前状态/条件/值。

解决方案:

如果在 If Block 中,您设置了任何 android widget.setVisibility(View.Gone) 的可见性,那么在 else 块中,您必须设置它与 vwith widget.setVisibility(View.Visible) 相反的可见性以克服上述问题。

 @Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {

    viewHolder.tvName.setText(ModelCategoryProducts.name.get(i));
    viewHolder.tvPrice.setText("Rs."+String.format("%.2f", Float.parseFloat(ModelCategoryProducts.price.get(i))));
    if(ModelCategoryProducts.special_price.get(i).equals("null")) {
        viewHolder.tvSpecialPrice.setVisibility(View.GONE); // here visibility is gone and in else it's opposite visibility i set.
        viewHolder.tvPrice.setTextColor(Color.parseColor("#ff0000"));
        viewHolder.tvPrice.setPaintFlags(0);// here paint flag is 0 and in else it's opposite flag that i want is set.
    }else if(!ModelCategoryProducts.special_price.get(i).equals("null")){
        viewHolder.tvPrice.setTextColor(Color.parseColor("#E0E0E0"));
        viewHolder.tvSpecialPrice.setVisibility(View.VISIBLE);
        viewHolder.tvSpecialPrice.setText("Rs." + String.format("%.2f", Float.parseFloat(ModelCategoryProducts.special_price.get(i))));
        viewHolder.tvPrice.setPaintFlags(viewHolder.tvPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
    }
    if (!ModelCategoryProducts.image_url.get(i).isEmpty()) {
        Picasso.with(context)
                .load(ModelCategoryProducts.image_url.get(i))
                .into(viewHolder.ivProduct);
    }

    viewHolder.setClickListener(new ItemClickListener() {
        @Override
        public void onClick(View view, int position, boolean isLongClick) {
            if (isLongClick) {
//                    Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position) + " (Long click)", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position), Toast.LENGTH_SHORT).show();
                Intent i = new Intent(context, ProductDetail.class);
                i.putExtra("position",position);
                i.putExtra("flagHlvCheck", 5);
                context.startActivity(i);
            }
        }
    });
}
祁权
2023-03-14

onBindHolder()被多次调用,因为recycler需要一个视图,除非当视图类型改变时有一个新的视图。因此,每次在子视图中设置可见性时,其他视图的状态也会发生变化。

无论何时上下滚动,这些视图都会使用错误的可见性选项重新绘制。

解决方案:

您有一个setValue方法检查值并设置为view。如果有必要,它调用另一个方法“showView”。您需要实现else语句(值为0或null)并在那里隐藏视图...

void setValue(Object value, TextView textView, TableRow row, View seperator) {
    if (value != null) {
        if (!isEmpty(value.toString())) {
            textView.setText(String.valueOf(value));
            showViews(row, seperator);
        }
    } else
        hideViews(row, seperator);
}

private void showViews(TableRow row, View seperator) {
    row.setVisibility(View.VISIBLE);
    seperator.setVisibility(View.VISIBLE);
}

private void hideViews(TableRow row, View seperator) {
    row.setVisibility(View.INVISIBLE); // if there is a empty space change it with View.GONE
    seperator.setVisibility(View.INVISIBLE);
}
施阳曜
2023-03-14

在与同一问题斗争了大约24小时之后,我找到了一个适合我的解决方案。关键是使用 RecyclerView.ViewHolder 类的 setIsRecyclable() 方法。

下面是我的< code>onBindViewHolder()代码的一部分。

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    final DataSource dataSource = dataSourceList.get(position);

    holder.setIsRecyclable(false);

    holder.name.setText(dataSource.getName());
    holder.active.setChecked(dataSource.getActive());

    String logoStr = dataSource.getLogo();

    //Logo
    /**
     * Do all the logo insertion stunts here
     */
    /**
     * Register the changes to the Switch
     */
    holder.active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
            dataSource.setActive(isChecked);
        }
    });
}
 类似资料:
  • 我正在开发一个聊天应用程序。我有一个聊天活动,两个用户可以发送WhatsApp之类的消息,但我有个问题。 就像你在图中看到的(https://ibb.co/3cyYX01),滚动时视图乱糟糟的,我想我知道为什么了。 在查看了这些帖子后:RecyclerView在滚动时出错,Android:RecyclerView在滚动后内容出错 我假设问题可能出在函数中的回收器视图适配器中,因为我在某些视图(VI

  • 问题内容: 无论如何,我可以做到这一点,以便在内容加载后(通过Ajax)页面自动滚动到顶部吗? 这是我显示内容的代码: 因此,在“视图区域”加载其内容之后,我可以使页面自动滚动到顶部吗? 问题答案: 只需使用滚动功能 如果您要使用jQuery,那么这里是一个很好的平滑示例:) 从链接: 放入代码中

  • 问题内容: 在下面的示例中,如果1000都是int(我认为它们都是),为什么底部不能编译? 问题答案: 经营者 运算符将操作数组合成表达式。 比较在其他地方讨论。对于其他二进制运算符,除非操作涉及移位或未类型化的常量,否则操作数类型必须相同。对于仅涉及常量的操作,请参见关于常量表达式的部分。 除移位操作外,如果一个操作数是未类型化的常量,而另一个操作数不是,则该常量将转换为另一种操作数的类型。 例

  • 我在Scrollview中有Recyclerview 现在,滚动时,layoutStaticContent保持固定在顶部

  • 问题内容: 我正在尝试使用反射使匿名类的实例。但是有时我在实例化过程中看到了奇怪的行为。 请看看这些类似的代码片段 该代码运行良好,并且预期输出 之后,我决定以简单的方式更改代码(只是添加了java.util.Calendar) 这是我得到的输出: 如您所见-尚未创建新实例。 有人能解释一下这种变化的原因吗? 谢谢 问题答案: 这是一个非常简单的问题,答案很复杂。在我尝试解释时,请多多包涵。 查看

  • 问题内容: 我正在运行Tomcat应用程序,并且需要显示一些时间值。不幸的是,时间要花一个小时了。我调查了一下,发现我的默认TimeZone设置为: 而不是太平洋时区。当我尝试打印默认时区的显示名称时,这会进一步指示,并且显示为 “ GMT-08:00”,这似乎向我表明它未正确设置为美国太平洋时区。我在从Gutsy Gibbon升级的Ubuntu Hardy Heron上运行。 我是否可以更新配置