2013-06-27 49 views
3

我有一个活动,在视图上绘制一些图标。我用`notifyDataSetChanged`丢失了什么?

它在onCreate()中设置了一个list和listAdapter。

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

使外部代码,可以调用UI线程,并指定新的列表到适配器,并使其通知通过notifyDataSetChange()

的变化。然而,新的图标中没有画出,但只有离开,又回到了后活动。

我该如何解决这个问题?

我已经试过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(); 
    } 

} 
+0

即使你说你确定它在UI线程中,请尝试在'CategoriesActivity.this'中放置'refreshListIcons()'调用。runOnUiThread()' –

+0

没有帮助。我努力了。它甚至可能导致崩溃? –

+0

它不应该。编辑你的问题,并发布你如何尝试它,以及你在logcat中遇到了什么错误。 –

回答

1

一个肮脏的黑客要做到这一点,如果你有太多的问题,获得新的通知,并在情况下,你没有在适配器数据显著量,你总是可以创建一个新的适配器和分配它的名单list.setAdapter(adapter);迫使名单从零开始重新把它翻过来...

关注!

2

您应该延长ArrayAdapter而不是BaseAdapter

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

这个类是适用于数组和集合,它正确地处理关于内部状态的所有顾虑。

在这种情况下使用clear接着addAll在适配器呼叫notifyDataSetChanged之前对象本身。另一个问题是更改绑定到您的Adapter的数组或集合。

我发现一个非常出色地完成此教程:

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

希望它可以帮助!最好的祝福 !!

1

我不认为你可以更新运行时为你的适配器供电的列表的内存位置。这是不允许的:

this.values = values; 

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

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

否则,你将需要每次创建一个新的适配器你可以调用setValues并通过指向新的适配器来更新你的列表视图。我会尝试链接到当我找到它时阅读这篇文章的文章。希望这可以工作。

相关问题