2013-07-31 3 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 отсутствует, заключается в том, что элемент списка (с использованием рекомендуемой реализации адаптера) получает рециркуляцию, как только он отключается, независимо от того, выбран ли элемент или нет. Я отправлю свое решение после того, как смогу выполнить свои требования. – 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 as) в конечную переменную или поле, которое будет использоваться при следующем вызове onItemSelected.

, например, вот модель объекта: общественного класса YourModelObject { общественного YourModelObject (String dataString, внутр dataInt) { this.dataString = dataString; this.dataInt = dataInt; } private String dataString; private int dataInt; // здесь некоторые добытчики, сеттеров и методы ... }

и вот ListView его отображения:

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

это так, как вы только манипулировать данными после того, как пункт потерял фокус (и новый выбранный), и вы уверены в согласованности своих данных, поскольку на самом деле вы не сохраняете представление, которое перерабатывается, а только те данные, которые он использовал.Надеюсь, вы сочтете это полезным :)

Смежные вопросы