2013-07-31 58 views
1

我在ListView中有一堆物品。每個項目包含幾個可編輯的視圖。我想保存用戶對這些的更改。要保存的事件發生在某個項目失去焦點時。OnItemSelectedListener,ListView和物品回收

我目前看到2種方式:

View.OnFocusChangeListener() with onFocusChange(View v, boolean hasFocus) 

這工作,但凌亂,因爲每個項目包含幾個可編輯的意見。當整個物品散焦時,我寧願保存。我迄今爲止的簡化嘗試只是複雜的事情。

如果有這將是完美的一個OnItemDeSelectedListener,但只有相反:

AdapterView.OnItemSelectedListener() with onItemSelected(AdapterView<?> adapterView, View view, int i, long l) 

表面上這看起來不錯。我只是創建變量lastSelectedView,所以我知道最後選擇(取消選擇)的項目是什麼。 問題是ListView如何回收視圖。我相信不能保證適配器沒有回收lastSelectedView,並因此改變了它所包含的數據。這是一個合理的假設嗎?

有沒有一種合理的方法來解決OnItemSelectedListener的回收視圖問題?

+0

你爲什麼要存儲最後修改的視圖而不是基礎模型?您應該在每次修改後更新列表視圖適配器中的數據。或者因爲您希望在項目焦點更改時執行此操作,請創建適配器所持數據類型的本地副本,但不要創建視圖。 – mpellegr

+1

嗯......謝謝你。你幫我意識到我的錯誤。沒有OnItemDeSelectedListener的原因是因爲列表項(使用推薦的Adapter實現)在屏幕熄滅後立即被回收,無論項目是否仍被選中。 一旦我能夠滿足我的要求,我會發布我的解決方案 – Ian

+0

我認爲沒有取消選擇的監聽者的原因是因爲沒有真正的處理多選和單選模式的選擇的一般方法。 – mpellegr

回答

0

如果您使用的是單個選擇,則選擇其他項目將「取消」當前項目。此時,您可以將更改應用到適配器中的本地存儲的項目副本。我不相信你應該使用onItemSelected()或onItemDeselected()中傳遞的視圖作爲編輯數據的模型。就像我說的,這是最好的創建當前正在編輯適配器數據類型的項目,並在onSelectedListener(),您將適用從編輯的項目更改到相應項目的適配器。事情是這樣的:

ListView myListView; 
    Object objectCurrentlyEditing; 
    int positionCurrentlyEditing; 
    myListView.setOnItemSelectedListener(new OnItemSelectedListener(){ 

     @Override 
     public void onItemSelected(AdapterView<?> arg0, View arg1, 
       int position, long arg3) 
     { 
      myListView.getAdapter().getItem(positionCurrentlyEditing).update(objectCurrentlyEditing); 

      positionCurrentlyEditing = position; 
      objectCurrentlyEditing = myListView.getAdapter().getItem(position); 
     } 

     @Override 
     public void onNothingSelected(AdapterView<?> arg0) { 
      // TODO Auto-generated method stub 

     } 
    }); 

更新功能將是多麼列表項,他們不再選擇後保存。該方法假定您使用單選模式。

0

我的答案與此處的其他答案類似,試圖解決回收問題有點不同 - 這將有點循環,因此可以讀取兩次: 在onItemSelected中,首先使用您保存的數據先前調用onItemSelected。 比保存從當前視圖(發送到onItemSelected作爲參數),以最終變量或字段中的數據被上到onItemSelected下一呼叫使用。

例如,這裏有一個模型對象: 公共類YourModelObject { 公共YourModelObject(字符串dataString,INT dataInt){ this.dataString = dataString; this.dataInt = dataInt; } private String dataString; private int dataInt; //這裏有一些的getter,setter和方法... }

和這裏的列表視圖中顯示它:

ListView myListView; 

ArrayList<YourModelObject> listOfModelObjects; 
//somewhere before onItemSelected listOfModelObjects is initialized with data 

final YourModelObject lastItemData; //this can either be final, or an instance variable. 

myListView.setOnItemSelectedListener(new OnItemSelectedListener(){ 

    @Override 
    public void onItemSelected(AdapterView<?> parent, View view, int i, long l) 
    { 
     //use last saved data: 
     if (lastItemData != null){ 
      //do some stuff with lastItemData 
     } 
     //save current data for next call: 
     TextView tv = (TextView) view.findViewById(someId); 
     NumberPicker np = (NumberPicker) view.findViewById(anotherId); 
     String dataString = tv.getText().toString(); 
     int dataInt = np.getValue(); 
     lastItemData = new YourModelObject(dataString , dataInt); 
    } 

    @Override 
    public void onNothingSelected(AdapterView<?> parent) { 
    } 
}); 

這種方式,你只有在項目失去焦點(和新的選擇的操作數據),你看好你的數據的一致性,因爲你真的不認爲被回收但是僅僅使用數據它來存放視圖。希望你找到它有用:)