Вне контроля ListView - PullRequest
       21

Вне контроля ListView

1 голос
/ 18 августа 2010

У меня проблема с ListActivity. Я расширил ArrayAdapter и переопределил getView, чтобы заполнить данные для каждой строки. Я выбрасываю некоторые данные из ArrayList моего адаптера в TextView.

Моя проблема в том, что при прокрутке TextView каждой строки заполняется текстом, которого нет в соответствующих данных ArrayList. Я имею в виду: скажем, у меня есть строка вверху моего списка с TextView, который заполнен пустой строкой. Если я нахожусь в нижней части своего списка и вижу строку с TextView, заполненную «bob», и я щелкаю, чтобы прокрутить вверх, строка вверху может теперь иметь «bob» в его TextView, но данные в этот индекс моего ArrayList не содержит "bob." Содержит пустую строку (фактически ноль). Если я продолжу прокручивать вверх и вниз, другие строки будут заполняться (или стираться) данными, которые не соответствуют содержимому ArrayList адаптера.

Чтобы это произошло, мне не нужно быстро прокручивать ListView. Однако, чем быстрее я прокручиваю, тем больше перепутывается строк.

Вот мой код. Я понимаю, что использую findViewById каждый раз, когда вызывается getView, но это не относится к делу. Я называю это против convertView; поэтому он должен получить правильный TextView в каждой строке, да?

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // get the View for this list item
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

    // get the next object
    MyListItem myItem = m_items.get(position);

    // set up the list item
    if (myItem != null) {
        TextView txtName = (TextView) v.findViewById(R.id.mylist_name);

        // set text
        if (txtName != null && myItem.getName() != null) {
            txtName.setText(myItem.getName());
        }
    }

   // return the created view
    return v;
}

Ответы [ 2 ]

2 голосов
/ 18 августа 2010

Я думаю, что проблема заключается в вашей проверке if (myItem! = Null) внизу.

Попробуйте добавить в этот блок инструкцию else, которая устанавливает для textview пустую строку.

Вот так:

// set up the list item 
TextView txtName = (TextView) v.findViewById(R.id.mylist_name); 
if (myItem != null) {  
    // set text 
    if (txtName != null && myItem.getName() != null) { 
        txtName.setText(myItem.getName()); 
    } else
    {
        txtName.setText("");
    }
} 
else
{
    txtName.setText("");
}

В конвертированном представлении все еще будут храниться старые данные, когда они будут переданы вам. Вам нужно намеренно перезаписать его, даже если ваши данные неверны, или он сохранит свои старые данные.

1 голос
/ 18 августа 2010

Обменяйте это

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

с этим

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, parent, false);
    }

Вы должны передать "false" методу инфляции (...).

Если выУ вас есть время, взгляните на сессию ввода-вывода в этом году об Android ListView: http://code.google.com/events/io/2010/sessions/world-of-listview-android.html

Это действительно стоит посмотреть или хотя бы пролистать слайды.Они также онлайн.

На основе ваших отзывов позвольте мне предложить способ связывания данных с ArrayAdapter.Возможно, это решит вашу проблему.

public class MyTestArrayAdapter extends ArrayAdapter<MyDataModel>{
   private final int resourceId;

   public MyTestArrayAdapter(Context context, int resourceId, List<MyDataModel> myDataModelList) {
      super(context, resourceId, myDataModelList);
      this.resourceId = resourceId;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
      if(convertView == null){
         LayoutInflater inflater = (LayoutInflater)getContext().getSystemService....
         convertView = inflater.inflate(resourceId, parent, false);
      }

      MyDataModel modelObj = getItem(position);

      TextView someDataView = convertView.findViewById(....);
      someDataView.setText(modelObj.getDataText());
      ...

      return convertView;
   }

}

Я думаю, вам не нужно передавать свои данные в качестве члена вашего ArrayAdapter. (я не пытался ни скомпилировать, ни запустить это, поэтому может потребоваться некоторая корректировка)

...