1

我有Activity一个ListView附加到一个custom adapter.

我有一个回调,表明一个可绘制项目已完成下载。

它被多次调用(每个资源都被下载)。

在我的回调中,我切换到 ui-thread 并将一个新数组设置为同一个适配器。

然后我打电话adapter.notifyDataSetChanged()

但活动列表不会刷新为新图标。

我还需要做什么?

1)打电话mListView.requestLayout()?但我怎么知道什么时候?

notifyDataSetChanged异步一样,我不知道什么时候完成。

2)覆盖adapter's destroyView?所以我不会创建一个新的listItem,而是使用现有的?

我的适配器代码:

公共类 SettingValueAdapter 扩展 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();
}

}

MyActivity的代码:

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

    SettingValueAdapter adapter;
    ListView            mListView;

    @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;

                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);
            }
        });
        mListView = (ListView) findViewById(R.id.settingsValueList);
        mListView.setAdapter(adapter);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                Intent intent = new Intent(CategoriesActivity.this,
                        SearchActivity.class);
                intent.putExtra(PublicMacros.SEARCH_CATEGORY,
                        categories[position].value);
                intent.putExtra(PublicMacros.SEARCH_MODE,
                        PublicMacros.FREE_SEARCH);
                startActivityForResult(intent, 1);
            }
        });
    }

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

        if (resultCode == RESULT_OK) {
            setResult(RESULT_OK);
            finish();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    public void refreshListIcons() {

//      if (categories != null) {
//          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");
//          }
//          

            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);
        }

    }
}

refreshIconsList从回调中调用。

但是,正如我所说的 - 列表不会在运行时刷新,但只有在存在并重新进入活动之后才会刷新。

我试过这个,但没有帮助:

    public void refreshListIcons() {

//      if (categories != null) {
//          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");
//          }
//          
        runOnUiThread(new Runnable()  {

        @Override
        public void run() {
            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();
            }
        }
        });
    }
4

2 回答 2

1

通常使用notifyDataSetChanged()会起作用。由于您的值只是一个数组,因此您使用扩展BaseAdapter而不是(它为底层数组ArrayAdapter提供add remove和功能)是否有特殊原因。clear我怀疑 usingBaseAdapter并没有以您可能想要的方式通知。如果这对您不起作用,请尝试在设置新值之后使用强制刷新子invalidate()视图View

顺便说一句,如果您打算在此列表中包含许多行以提高速度,我强烈建议您使用“视图持有者模式”。

于 2013-06-30T13:26:37.917 回答
0

尝试这个:

  • mListView.setAdapter(适配器); 在活动中的 onCreate() 上。
  • 公共无效刷新列表图标(){

    runOnUiThread(new Runnable()  {
    
    @Override
    public void run() {
        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.addAll(values); // *** ADD THIS LINE***
        }
    }
    });
    

    }

问题是当您在回调后 setAdapter 时。所以你必须在调用之前初始化适配器并在回调之后添加值

于 2016-07-07T15:26:00.037 回答