1

我有一个带有 viewList + 自定义适配器的活动。

我想在运行时更新 viewList(在某些资源完成下载时使用回调)。我调用 ui-thread 来调用这个方法:

    public void refreshListIcons() {

            if (categories != null) {

                SettingsValue[] values = adapter.getValues();
                for (int i = 0; i < values.length; i++) {
                    values[i].icon = ResManager
                            .GetSkinDrawable(categories[i].iconName + ".bin");
                }

                adapter.setValues(values);

                mListView.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
    }

然后adapter.getView调用该方法:

但为什么convertView==null呢?

我理解第一次创建活动时。

但现在这是我第二次(运行时更新)。

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.settings_item, null);
        }
...
}

它会导致重新充气太多次并使我的应用程序崩溃。

我的整个适配器的代码:

package com.waze.settings;


public class SettingValueAdapter extends BaseAdapter {

    private SettingsValue[] values;
    private LayoutInflater inflater;
    public SettingValueAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }

    public SettingsValue[] getValues() {
        return values;
    }

    @Override
    public int getCount() {
        if (values == null) {
            return 0;
        }
        return values.length;
    }


    @Override
    public Object getItem(int arg0) {
        return values==null? null : values[arg0];       
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.settings_item, null);
        }
        SettingsValue item = values[position];
        CheckedTextView name = (CheckedTextView) convertView.findViewById(R.id.itemText);
        ImageView iconView = (ImageView) convertView.findViewById(R.id.itemIcon);
        if (iconView != null && (item != null) && (item.icon != null)) {
            iconView.setImageDrawable(item.icon);
            iconView.setVisibility(View.VISIBLE);
        } else {
            iconView.setVisibility(View.GONE);
        }
        name.setText(item.display);
        name.setChecked(item.isSelected);
        View container = convertView.findViewById(R.id.itemContainer);
        if (position == 0) {
            if (position == values.length-1) {
                container.setBackgroundResource(R.drawable.item_selector_single);
            } else {
                container.setBackgroundResource(R.drawable.item_selector_top);
            }
        } else {
            if (position == values.length-1) {
                container.setBackgroundResource(R.drawable.item_selector_bottom);
            } else {
                container.setBackgroundResource(R.drawable.item_selector_middle);
            }
        }
        container.setPadding(0, 0, 0, 0);
        return convertView;
    }

    public void setValues(SettingsValue[] values) {
        this.values = values;
        notifyDataSetChanged();
    }
}
4

1 回答 1

0

我想你不应该再次设置适配器。而是将您的刷新方法修改为:

public void refreshListIcons() {

        if (categories != null) {

            SettingsValue[] values = adapter.getValues();
            for (int i = 0; i < values.length; i++) {
                values[i].icon = ResManager
                        .GetSkinDrawable(categories[i].iconName + ".bin");
            }

            adapter.notifyDataSetChanged();


           /* 
             adapter.setValues(values);
             mListView.setAdapter(adapter);
             adapter.notifyDataSetChanged();*/
        }
}

还要在适配器中添加一个 viewHolder 类。

于 2013-06-30T14:22:41.577 回答