【问题标题】:getTag Getting Wrong Tag In ListViewgetTag 在 ListView 中获取错误的标签
【发布时间】:2014-07-23 06:58:35
【问题描述】:

我有一个列表视图,每个项目都有一个开/关按钮。

加载时,所有用户都已关闭。我按下 user1,它打开并将标签设置为“on”。当我向下滚动时,user7 已打开。在我的日志猫中,我可以看到 user7 正在从 user1 获取标签。上下滚动似乎会继续这种收集错误标签的视图模式。

我之前在 listview 回收方面遇到过问题,但只需确保我在 getView 中正确设置了所有内容即可解决。

很遗憾,经过数小时的故障排除/反复试验,我仍未解决问题。

非常感谢任何帮助!

这是我的getview。我对用户名进行编号并将其添加到日志标签中,这样我就可以看到调用了哪一个来确定项目 1 中的标签正用于项目 7,等等:

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        final ViewHolder holder;
        if (convertView == null){

            convertView = inflater.inflate(R.layout.list_item, null);

            holder = new ViewHolder();
            holder.name = (TextView)convertView.findViewById(R.id.name);
            holder.availablebutton = (ImageView)convertView.findViewById(R.id.availablebutton);


            convertView.setTag(holder);

        } else {

            holder = (ViewHolder)convertView.getTag();
        }



        final HashMap<String,String> item = (HashMap<String,String> ) items.get(position);
        if (item != null)
        {

                if (holder.availablebutton.getTag() != null) {

                    Log.d("AB gettag is not null:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));

                    if (("on").equals(holder.availablebutton.getTag().toString())) {
                        holder.availablebutton.setImageResource(R.drawable.on1);
                        Log.d("tag 1:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                        }
                    else {
                        holder.availablebutton.setImageResource(R.drawable.off1);
                        Log.d("tag 2:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                    }

                    } else {

                        if ("2".equals(item.get(TAG_AVAILABLE))) {
                            holder.availablebutton.setImageResource(R.drawable.on1);
                            holder.name.setTag("on");
                            Log.d("tag 3:", holder.name.getTag() + item.get(TAG_USERNAME));
                            }
                        else {
                            holder.availablebutton.setImageResource(R.drawable.off1);
                            holder.name.setTag("off");
                            Log.d("tag 4:", holder.name.getTag() + item.get(TAG_USERNAME));
                        }

                       }



            holder.availablebutton.setOnTouchListener(
                    new View.OnTouchListener()
                    {

                        @Override
                        public boolean onTouch(View v, MotionEvent event) {

                    if (holder.availablebutton.getTag() != null) {

                            if (("on").equals(holder.availablebutton.getTag().toString())) {
                                holder.availablebutton.setImageResource(R.drawable.off1);
                                holder.availablebutton.setTag("off");
                                Log.d("button pressed 1:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                                }
                            else {
                                holder.availablebutton.setImageResource(R.drawable.on1);
                                holder.availablebutton.setTag("on");
                                Log.d("button pressed 2:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                            }

                    } else {

                        if (("on").equals(holder.name.getTag().toString())) {
                            holder.availablebutton.setImageResource(R.drawable.off1);
                            holder.availablebutton.setTag("off");
                            Log.d("button pressed 3:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                            }
                        else {
                            holder.availablebutton.setImageResource(R.drawable.on1);
                            holder.availablebutton.setTag("on");
                            Log.d("button pressed 4:", holder.availablebutton.getTag() + item.get(TAG_USERNAME));
                        }

                    }

                            return false;
                        }
                    }
                );

        }

        return convertView;
    }

这是我的 logcat,我希望它有意义:

第一次加载:

07-22 23:41:00.948: D/tag 4:(27178): offUser1
07-22 23:41:00.958: D/tag 4:(27178): offUser2
07-22 23:41:00.968: D/tag 4:(27178): offUser3
07-22 23:41:00.978: D/tag 4:(27178): offUser4

按下用户 1 的按钮:

07-22 23:41:09.148: D/button pressed 4:(27178): onUser1

按下按钮后向下滚动:

07-22 23:41:15.438: D/tag 4:(27178): offUser5
07-22 23:41:15.488: D/tag 4:(27178): offUser6
07-22 23:41:15.518: D/AB gettag is not null:(27178): onUser7
07-22 23:41:15.518: D/tag 1:(27178): onUser7
07-22 23:41:15.548: D/tag 4:(27178): offUser8

【问题讨论】:

  • 在具有 ViewHolder 模式的列表视图中,相同的视图返回为 convertview..出于您的目的,您需要维护 sparseBooleanArray 以及单击的项目位置及其值。

标签: android listview android-listview


【解决方案1】:

您不能仅在标签中保存该值。当视图被回收时,这意味着当视图在滚动时关闭,完全相同的视图将出现在列表视图中。这就是为什么在 getView 方法中使用 convertView 的原因。您可以用新数据填充此回收视图,它看起来不错,但您的标签仍然相同。 即使您不回收视图(总是在不使用 convertView 的情况下膨胀视图) - 它仍然无法工作,因为您的标签将被简单地垃圾收集。

例如,您需要做的是:创建一个外部哈希集,在其中保留所有打开的 ID。在 getView 方法中,你可以检查你的 id 是否在 hashset 中,然后用它做你想做的事情。

此外,当您需要的唯一情况是列表项的 ON/OFF 时 - CHOICE_MODE_MULTIPLE 将是一个不错的选择。你必须阅读更多关于它的信息START HERE

【讨论】:

  • 感谢详细的解释,我试试看!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多