3

我有一个在视图上绘制一些图标的活动。

它在 中设置一个列表和 listAdapter onCreate()

我已将将列表分配给我的适配器的代码提取到公共方法中。

这样外部代码就可以调用 UI 线程并将新列表分配给适配器并使其通过notifyDataSetChange()

然而,新图标不会被绘制,而只是在离开并返回 Activity 之后。

我怎样才能解决这个问题?

我试过 adapter.clear()

并仔细检查了 UI 线程运行此代码。

还有什么?

public class CategoriesActivity extends ActivityBase {
    private Category[] categories;

    SettingValueAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_values);
        ((TitleBar)findViewById(R.id.theTitleBar)).init(this,DisplayStrings.DS_CATEGORIES);

        adapter = new SettingValueAdapter(this);

        DriveToNativeManager nativeManager = DriveToNativeManager.getInstance();
        nativeManager.getCategories(new CategoriesListener() {

            @Override
            public void onComplete(Category[] aCategories) {
                categories = aCategories;
                refreshListIcons();
            }
        });
        final ListView list = (ListView)findViewById(R.id.settingsValueList);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            ..
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        ..
    }

    public void refreshListIcons()  {
        NativeManager nativeManager = AppService.getNativeManager();
        SettingsValue[] values = new SettingsValue[categories.length];
        for (int i = 0; i < categories.length; i++) {
            values[i] = new SettingsValue(categories[i].value, nativeManager.getLanguageString(categories[i].displayString), false);
            values[i].icon = ResManager.GetSkinDrawable(categories[i].iconName + ".bin");
        }
        adapter.setValues(values);
    }   
}




public class SettingValueAdapter extends BaseAdapter {

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

...

    @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) {
            ..
        return convertView;
    }
    public void setValues(SettingsValue[] values) {
        this.values = values;
        notifyDataSetChanged();
    }

}
4

3 回答 3

2

您应该扩展ArrayAdapter而不是BaseAdapter

http://developer.android.com/reference/android/widget/ArrayAdapter.html

此类适用于数组和集合,它可以正确处理有关内部状态的所有问题。

在这种情况下 useclear后跟addAllat Adapter 对象本身在 call 之前notifyDataSetChanged。另一种方法是更改​​绑定到您的Adapter.

我在这里找到了一个做得很好的教程:

http://www.vogella.com/articles/AndroidListView/article.html

希望能帮助到你 !!此致 !!

于 2013-07-02T18:13:28.083 回答
1

我认为您无法在运行时更新为适配器供电的列表的内存位置。这是不允许的:

this.values = values;

如果您知道项目的数量不会改变,请使用以下代码:

public void setValues(SettingsValue[] values) {
    for (int i = 0; i < values.length; i++) {
        this.values[i] = values[i];
    }
    notifyDataSetChanged();
}

否则,每次调用 setValues 并通过指向新适配器来更新列表视图时,您都需要创建一个新适配器。当我找到它时,我会尝试链接到我读过这篇文章的地方。希望这有效。

于 2013-07-06T10:11:55.353 回答
1

一个肮脏的黑客来做到这一点,如果您在获取新通知时遇到太多问题,并且如果您在适配器中没有大量数据,您始终可以创建一个新适配器并将其分配给list.setAdapter(adapter);强制列表的列表从头开始重新渲染它......

问候!

于 2013-07-01T18:42:02.003 回答