【问题标题】:Android listview mixes rows when scrollingAndroid listview在滚动时混合行
【发布时间】:2016-05-19 16:28:44
【问题描述】:

好的,我现在放弃了,请帮帮我。

我看到网上到处都是像我这样的问题。 但他们都没有帮助我,因为 90% 的问题都犯了一个简单的错误,例如将设置方法放入if语句中。

我想我知道基础知识,不要犯简单的错误,但它仍然不起作用。

我有一个 ListView,每一行都有一个 TextView 和四个 RadioButton。您可以在每一行中设置一个。那很简单。 我使用 ViewHolder 进行平滑滚动,因为列表中有几百行。 当你开始滚动时,它会搞砸一切:选中的 RB 会被取消选中,反之亦然。

开玩笑的是,这(仅)是一个视觉错误,因为当保存设置时,只有实际触摸的行处于选中状态,所以基本上它可以工作,但我不能告诉我的用户忽略你看到了什么:)

我用该代码尝试了所有方法,错误在哪里?

public View getView(final int position, View convertView, ViewGroup parent) {

    // i need a final modifier because I use the holder in Listener
    final ViewHolder holder;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.hatranyos_lista_row, parent, false);
        holder = new ViewHolder();

        holder.nev = (TextView) convertView.findViewById(R.id.nev);
        holder.rg = (RadioGroup) convertView.findViewById(R.id.radioTipus);
        holder.rb_elit = (RadioButton) convertView.findViewById(R.id.radioElit);
        holder.rb_atl = (RadioButton) convertView.findViewById(R.id.radioAtlagos);
        holder.rb_atl_a = (RadioButton) convertView.findViewById(R.id.radioAtlagAlatt);
        holder.rb_rossz = (RadioButton) convertView.findViewById(R.id.radioRossz);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // one listener for the RadioGroup. I think its okay, because when i remove it, my problem still exists
    holder.rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            if (holder.rb_elit.isChecked()) {
                values.get(position).setH_statusz(1);
            }
            if (holder.rb_atl.isChecked()) {
                values.get(position).setH_statusz(2);
            }
            if (holder.rb_atl_a.isChecked()) {
                values.get(position).setH_statusz(3);
            }
            if (holder.rb_rossz.isChecked()) {
                values.get(position).setH_statusz(4);
            }
        }
    });

    // setters after the if statement
    holder.nev.setText(values.get(position).getUtvonal() + "/" + values.get(position).getPos() + " " + values.get(position).getNev());

    int h_statusz = values.get(position).getH_statusz();

    // and finally (pre)setting the RBs. I know rows will recycle so I tried to set in every case
    switch (h_statusz) {
    case 1:
        holder.rb_elit.setChecked(true);
        holder.rb_atl.setChecked(false);
        holder.rb_atl_a.setChecked(false);
        holder.rb_rossz.setChecked(false);
        break;
    case 2:
        holder.rb_elit.setChecked(false);
        holder.rb_atl.setChecked(true);
        holder.rb_atl_a.setChecked(false);
        holder.rb_rossz.setChecked(false);
        break;
    case 3:
        holder.rb_elit.setChecked(false);
        holder.rb_atl.setChecked(false);
        holder.rb_atl_a.setChecked(true);
        holder.rb_rossz.setChecked(false);
        break;
    case 4:
        holder.rb_elit.setChecked(false);
        holder.rb_atl.setChecked(false);
        holder.rb_atl_a.setChecked(false);
        holder.rb_rossz.setChecked(true);
        break;
    default:
        holder.rb_elit.setChecked(false);
        holder.rb_atl.setChecked(false);
        holder.rb_atl_a.setChecked(false);
        holder.rb_rossz.setChecked(false);
        break;
    }

    return convertView;
}

static class ViewHolder {
    TextView nev;
    RadioGroup rg;
    RadioButton rb_elit;
    RadioButton rb_atl;
    RadioButton rb_atl_a;
    RadioButton rb_rossz;
}

【问题讨论】:

  • 覆盖监听器并将引用传递给非最终 Viewholder。
  • 好吧,我真的错过了@override,所以谢谢你。我将持有人移出 getView 并将其用作非最终版本,但问题仍然存在......
  • 尝试将 viewholder 设置为 group 上的标签,然后,而不是使用位置和 viewholder(您已声明为 final),只需使用该持有者(通过从广播集团)。您还需要持有对持有人正在显示的项目的引用(因此持有人需要有一个包含实际值的值字段)。希望这能解决您的问题。
  • 嗯,我对此有点困惑,所以你说我应该(设置)将持有者标记到 RadioGroup,而不是 View?而且我也不明白为什么需要对显示的项目进行此引用。

标签: android listview android-viewholder


【解决方案1】:

首先,取消您 RadioGroup 中的 OnCheckedChangeListener。然后设置每个按钮的检查状态。最后在最后注册一个新的 OnCheckedChangeListener。

我猜当您在组上设置侦听器后设置项目的检查状态时,每次都会调用侦听器。

【讨论】:

  • 我试过这个,但没有帮助。实际上(如果可能的话)现在更糟了。
  • 我认为,如果您对所看到的内容提供更详细的解释,并附有详细说明与您预期的不同之处的屏幕截图,将会有所帮助。
  • 我想是我写的:选中的单选按钮失去选中状态,并且滚动时未触及的 RB 进入选中状态。而且它有一些随机性,有时只有空的RB。
【解决方案2】:

最后 - 唯一有效的 - 我退出了 ViewHolder。 我修改了我的活动,列表包含的不是几百行,而是只有 10-20 行,并且在没有 ViewHolder 的情况下,滚动的行数很少。 如果我使用它,那个错误就在那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多