2013-06-27 44 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並通過指向新的適配器來更新你的列表視圖。我會嘗試鏈接到當我找到它時閱讀這篇文章的文章。希望這可以工作。

相關問題