android - 来自 CustomAdapter 的 getView() 的意外行为

标签 android listview

我有一个 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() 刷新适配器时在不更改数据的情况下,ViewHolder我通过打电话得到getTag()正在返回错误的标签。它工作得像

如果位置为 1,则 holder 对象位于位置 0 的 View 中。即;之前的对象被返回..

最后我找到了一个post

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

解决方案是

设置ListView的宽度至 MATCH_PARENT在 xml 中,在帖子中是 height .

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

最佳答案

似乎当您不使用此解决方法时,Android 必须多次调整 ListView 的布局大小,直到执行为止。这就是为什么有许多用户提示 getView() 被调用的次数超过了“应该”的次数。

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

--- 编辑 ---

here comes the confirmation ,第 48 页。希望对您有所帮助!

关于android - 来自 CustomAdapter 的 getView() 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21303046/

相关文章:

Android Application Init 和全局对象

android - 渲染问题 渲染过程中引发异常 : com/android/util/PropertiesMap

android - 除了使用 FileProvider 获取用于安装 Android apk 的 uri 之外,还有其他方法吗?

Android:ScrollView 内的 Listview

android - 单击时不检查复选框..但检查条件

android - 如何从 Couchbase 数据库中保存和获取数据并将其显示在 ListView 上?

java - Android Studio 构建失败(java 编译器错误)

android - Listview 行顺序在 android 中的 listview 滚动时随机变化

android:删除 ListView 选择器

c# - ListView 中的 Xamarin Forms 按钮命令绑定(bind)