Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:RecyclerView内容在滚动后混乱不堪_Android_Android Recyclerview_Android Viewholder - Fatal编程技术网

Android:RecyclerView内容在滚动后混乱不堪

Android:RecyclerView内容在滚动后混乱不堪,android,android-recyclerview,android-viewholder,Android,Android Recyclerview,Android Viewholder,我使用RecyclerView来显示标记列表,值的每个标记都显示为CardView。但在向下滚动RecyclerView并向后滚动后,卡中的某些内容会丢失,如下面的两个屏幕截图所示。滚动后,红色矩形中的内容将丢失 在滚动之前 在滚动之后 我想知道这是否是RecyclerView的一个bug,在谷歌上搜索后没有找到解决方案 除标题外,所有视图都不可见,它们的可见性取决于标记的值 有人知道为什么会这样吗 这是因为在滚动时视图被重用。若要解决此问题,您需要重置已对其他单元可见的任何视图(在您的示例

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

在滚动之前

在滚动之后

我想知道这是否是RecyclerView的一个bug,在谷歌上搜索后没有找到解决方案

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


有人知道为什么会这样吗

这是因为在滚动时视图被重用。若要解决此问题,您需要重置已对其他单元可见的任何视图(在您的示例中为YUZME)

在setValue内部(对象值、TextView、TextView、TableRow行、视图分隔符),只需再次隐藏所有txtVize*


回收器视图以3个视图开始:

[0]FIZ104

[1] MAT102

[2] REK361

当视图滚动到底部时,将回收视图[0]和[1]。当您向后滚动到俯视图时,使用[2]显示FIZ104和MAT102中包含的数据,并且对REK361所做的任何更改仍然存在。

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

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

解决方案:

您有一个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);
}

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

无论何时上下滚动,这些视图都会使用错误的可见性选项重新绘制,因此请始终指定这两个条件,因为recycler视图不知道小部件的先前状态/条件/值

解决方案:

如果在If块中设置了任何android widget.setVisibility(View.go)的可见性,那么在else块中,您必须设置与vWidget.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);
            }
        }
    });
}

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

下面是我的
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);
        }
    });
}

若您在ex的可见性问题上遇到问题。若您已根据条件设置了视图的可见性,但若向下滚动,视图将刷新,并且回收器视图项内的视图的可见性将发生更改,从而违反条件

这里有一个解决方案:

1。首先将标记指定给要保持其可见性的视图。

    holder.myImageView.setTag(myTeamLists.get(position));
    MyDTOClass checkWetherToShow=(MyDTOClass)holder.myImageView.getTag();
2。现在应用您的条件并切换可见性

    if (checkWetherToShow.getHasToShowImage()){
        holder.myImageView.setVisibility(View.VISIBLE);
    }else{
        holder.myImageView.setVisibility(View.GONE);
    }

这里答案的关键是不要忘记else部分

我建议您编写自定义视图组件。设置可见性不是一个好的实现。你的项目是否在git上?所以我可以创建一个对它的拉取请求(dostum;)?我强烈建议您在继续之前重构代码。这是非常难以遵循的,你有很多意见的方式。您应该能够动态创建许多这样的代码,以帮助减少一些代码。我真的相信问题出在
onBindViewHolder
@EmreAktürk上,不幸的是它不在git上,因为它有我大学的一些特殊web服务。用自定义视图我可以实现什么,我不知道:)我不认为该做什么,任何帮助都会很好-JaredBurrows实际上视图的web服务太脏了。服务有10个Vize字段,所有字段都包含讲座分数。我试图检查服务中的Vize字段(标记)是否为空,然后显示文本视图。好的,然后。。。这是解决方法。。。您有一个setValue方法检查值并设置为view。如果需要,它调用另一个方法“showView”。您需要实现else语句(值为0或null)并在那里隐藏查看…感谢您的响应。我知道viewholder机制实际上我想做的是不回收视图或保持它们的状态,甚至用户滚动。我几乎想在6个小时内解决这个问题,尝试了所有方法,但没有一个有效。在OnBindHolder方法中。将recyclerview设置为不可回收即放弃recyclerview的目的。