【问题标题】:Unexpected behaviour from getView() of CustomAdapter来自 CustomAdapter 的 getView() 的意外行为
【发布时间】:2014-01-23 08:33:40
【问题描述】:

我有一个像这样的ViewHolder

    static class ViewHolder {
    protected String fileName;
    protected Bitmap bitmap = null;
    protected CheckBox checkBox;
    protected int position;
    protected int resourceId = 0;
    protected ImageView imageView;
    protected TextView textView;
}

在我的getView()

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;

    if(convertView != null)
    {
        ViewHolder holder = (ViewHolder) convertView.getTag();
        if(!holder.fileName.equals(fileList.get(position)))
            convertView = null;
    }
    if(convertView == null)
    {
        convertView = inflater.inflate(R.layout.image_layout, null, false);
        viewHolder = new ViewHolder();

        viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
        viewHolder.textView = (TextView) convertView.findViewById(R.id.text);

        // Set viewHolder attributes
        viewHolder.position = position;
        viewHolder.fileName = fileList.get(position);;

        // set the checkbox
        viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);

        // Set the path of the file
        final String filePath = context.getBasePath(position);

        if(new File(filePath).isDirectory())
        {
            viewHolder.imageView.setImageResource(R.drawable.folder);
            viewHolder.resourceId = R.drawable.folder;
        }
        else
        {
            String mimeType = Utility.getMimeType(filePath);
            if(mimeType.contains("image"))
            {
                loadImage(viewHolder, viewHolder.imageView, filePath);
            }
            else
                viewHolder.resourceId = handleFile(viewHolder.imageView, filePath);
        }
        convertView.setTag(viewHolder);
    }
    else
    {
        viewHolder = (ViewHolder) convertView.getTag();

        if(viewHolder.bitmap == null)
            viewHolder.imageView.setImageResource(viewHolder.resourceId);
        else
            viewHolder.imageView.setImageBitmap(viewHolder.bitmap);
    }

    viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton checkBox, boolean checked) {
            viewHolder.checkBox.setChecked(checked);
            listener.onFileStateChanged(viewHolder.position, checked);
        }
    });

    // set the fileName
    viewHolder.textView.setText(viewHolder.fileName);

    if(checkBoxVisibility)
        viewHolder.checkBox.setVisibility(View.VISIBLE);
    else
        viewHolder.checkBox.setVisibility(View.INVISIBLE);

    return convertView;
}

此时,当我使用notifydatasetChanged() 刷新适配器而不更改数据时,我通过调用getTag() 得到的ViewHolder 返回错误的标签。它就像

如果位置为 1,则持有者对象是位置 0 的视图。即;返回上一个对象..

最后我找到了post

这是不一样的,但使用相同的方法和解决方案对我有用..我不知道如何..

解决方案是

在xml中将ListView的宽度设置为MATCH_PARENT,在帖子中是height

有谁知道,这种行为的原因是什么?我找不到这个问题背后的逻辑

【问题讨论】:

  • 你能发布你的初始化ViewHolder的代码吗?
  • 我刚刚更新了整个代码

标签: android listview


【解决方案1】:

似乎当您不使用此解决方法时,Android 必须多次调整列表视图的布局,直到它被执行。这就是为什么有很多用户抱怨getView() 被调用的次数超过了它“应该”的次数。

无论如何,请注意getView() 不是按顺序调用的,它是按Android 确定的顺序调用的,所以不要指望按顺序显示标签。

--- 编辑---

还有here comes the confirmation,第 48 页。希望这会有所帮助!

【讨论】:

  • 我不知道这个的准确解释,但我的猜测是当宽度设置为MATCH_PARENT(实际上应该)时,Android已经正确渲染了布局,所以它是依次调用,因为 Android 认为每一行都同样“难以”呈现。另一方面,当设置为WRAP_CONTENT 时,除了显示布局外,还必须将每一行渲染为明确的布局,Android 会在渲染每一行后立即处理getView(),这意味着每一行都不会t 必须等于 render,这就是为什么它不是顺序的。
  • 感谢您尝试帮助我并解释您所知道的,可能是这样,但我正在寻找一些确切的解决方案,因为这是我们通常在每个程序上工作的,所以我不想做它没有知识
  • 我刚刚发现了这个:dl.google.com/googleio/2010/… 在第 48 页,有一些关于它的内容。很遗憾,它现在详细一点,但给出了一个想法。
  • 是的,那太好了......应该记录假设:(我们怎么知道它是否像这样???
  • 确实,有趣的是,我发现这是一个完全不同的主题 :-) 不过我会保留该页面,希望至少其他用户可以帮助您的问题(我赞成)
猜你喜欢
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
相关资源
最近更新 更多