2014-04-09 42 views
0

我參與了一個開源項目,該項目使用ListView來顯示一些數據,每個項目包含2 TextView項目R.id.card_column1R.id.card_column2,以便我們看到代表大量閃卡的某些數據的2列列表。是否可以更改現有SimpleAdapter的映射?

我們有一個固定的數據結構含有可以在列中示出的各種鍵/值對ArrayList<HashMap<String, String>> mCards,並使用SimpleAdaptermCards元件的HashMap中的給定的鍵/值對之間映射,和TextView項目如下:

mCardsAdapter = new SimpleAdapter(
      this, 
      mCards, 
      R.layout.card_item_browser, 
      new String[] {col1Key, col2Key}, 
      new int[] {R.id.card_column1, R.id.card_column2}); 

固定mCards結構和2個TextView元素組成的列之間的數據映射需要是可調整的,即,我們需要的是能夠改變col1Keycol2Key。我找不到任何方法來更改SimpleAdapter documentation中的from密鑰,所以我目前已經實現了這一點,只要用戶要求更改該列,只需調用的setAdapter()方法和包含更新密鑰的新SimpleAdapter。這種方法的問題是重置ListView中的垂直位置。

一個解決方案可能是改變數據結構本身,然後調用notifyDataSetChanged(),但是這個數組可能非常大,所以這種方法會浪費有價值的RAM,並且可能需要大量CPU時間來更新數據結構,所以我想避免這種方法。

所以我的問題是:

1)是否有可能動態改變映射的適配器,即改變from對象在構造函數中,而無需創建一個新的SimpleAdapter

2)如果不是,在ListView中改變映射而不丟失垂直滾動位置的最好方法是什麼?最好不要消耗任何額外的RAM,或者需要比創建新適配器更多的CPU。

+0

?是的,有可能,在需要的位置訪問列表,更改其數據,並在現有適配器上調用notifyDataSetChanged方法 –

+1

如果通過「映射」表示您的字符串數組,則您在適配器類中創建一個setter方法,新的「映射」,然後調用notifyDataSetChanged你在getView方法中處理sunch映射 –

+0

是的。謝謝,所以如果我理解正確,你說我必須繼承'SimpleAdapter',爲一個新的地圖變量提供一個set方法,然後通過重載'getView'手動實現映射過程?推測從「BaseAdapter」繼承將是更清潔的... –

回答

-1

感謝Mocialov鮑里斯的提示,這裏是供參考的完整的答案:

雖然它無法更新SimpleAdapter的映射,可以延長BaseAdapter和手動執行的映射。我們提供了一個setFromMapping()方法來更新數據結構和列之間的映射,並調用notifyDataSetChanged()。新的類MultiColumnListAdapter然後只是用同樣的方式,一個SimpleAdapter用於:

public class MultiColumnListAdapter extends BaseAdapter { 
    private List<? extends Map<String, ?>> mData; 
    private int mResource; 
    private String[] mFrom; 
    private int[] mTo; 
    private LayoutInflater mInflater; 


    public MultiColumnListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, 
      String[] from, int[] to) {    
     mData = data; 
     mResource = resource; 
     mFrom = from; 
     mTo = to; 
     mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 


    public View getView(int position, View convertView, ViewGroup parent) { 
     // Get the main container view if it doesn't already exist, and call bindView 
     View v;    
     if (convertView == null){ 
      v = mInflater.inflate(mResource, parent, false); 
      final int count = mTo.length; 
      final View[] columns = new View[count]; 
      for (int i = 0; i < count; i++) { 
       columns[i]=v.findViewById(mTo[i]); 
      } 
      v.setTag(columns);     
     } else { 
      v = convertView; 
     } 
     bindView(position, v); 
     return v; 
    } 

    private void bindView(int position, View v) { 
     // Draw the content in the columns 
     View[] columns = (View[]) v.getTag(); 
     final Map dataSet = mData.get(position); 
     for (int i = 0; i < mTo.length; i++) { 
      TextView col = (TextView) columns[i]; 
      col.setText((String) dataSet.get(mFrom[i])); 
     }   
    } 

    public void setFromMapping(String[] from){ 
     mFrom = from; 
     notifyDataSetChanged(); 
    } 

    public String[] getFromMapping(){ 
     return mFrom; 
    }   

    @Override 
    public int getCount() { 
     return mData.size(); 
    } 


    @Override 
    public Object getItem(int position) { 
     return mData.get(position); 
    } 


    @Override 
    public long getItemId(int position) { 
     return position; 
    } 
} 
要在mCards列表更改元素
相關問題