Android - список возвращается наверх после обновления - PullRequest
1 голос
/ 07 сентября 2010

У меня есть список, который обновляется каждые 2 секунды с помощью метода PostDelayed () обработчика.

Каждые 2 секунды запускается AsyncTask, который выполняет HTTP-запрос GET, превращает JSON в список объектов, а затем устанавливает ListAdapter:

 MyListAdapter adapter = new MyListAdapter(someObjects);
 setListAdapter(adapter);

Моя проблема в том, что каждый раз, когда задача завершается (то есть примерно каждые две секунды), мой список возвращается наверх, даже если я прокрутил вниз до середины или до конца списка. Это будет очень раздражать для конечного пользователя, поэтому мне нужно, чтобы список обновлялся в фоновом режиме, как это происходит, но текущее представление списка не должно возвращаться к вершине при завершении AsyncTask.

Я могу включить любой другой необходимый код. Я немного новичок в разработке Android, поэтому я не уверен, что полезно для других.

Дополнительная информация

Принимая предложения от hacksteak25, я могу добраться до точки, где я пытаюсь удалить все данные из адаптера, а затем добавить их обратно по одному объекту за раз. Это не конечное решение, так как это, вероятно, по-прежнему вызывает скачок экрана, но я пытаюсь использовать его как доказательство того, как я могу объединить данные в какой-то момент.

Моя проблема в том, что я вызываю следующий код:

 MyListAdapter adapter = (MyListAdapter)getListAdapter();
 adapter.clear();
 for(MyObject myObject : myObjects)
 {
  adapter.add(myObject);
 }

После первого вызова «add (myObject)» вызывается метод getView () MyListAdapter. Закрытый внутренний ArrayList пользовательского адаптера на данный момент пуст, либо потому, что я установил адаптер без myObjects в onCreate (), либо потому, что я вызвал clear () для адаптера, я не уверен. В любом случае это приводит к сбою getView, так как в ArrayList нет объектов, из которых можно получить представление.

getView () выглядит так:

public View getView(int position, View convertView, ViewGroup parent)
{
 ViewHolder holder;
 LayoutInflater mInflater = getLayoutInflater();

 if (convertView == null)
 {
  convertView = mInflater.inflate(R.layout.myObject, null);

  holder = new ViewHolder();
  holder.someProperty = (TextView)convertView.findViewById(R.id.someProperty);
  holder.someOtherProperty = (TextView)convertView.findViewById(R.id.someOtherProperty);
  holder.someOtherOtherProperty = (TextView)convertView.findViewById(R.id.someOtherOtherProperty);

  convertView.setTag(holder);
 }
 else
 {
  holder = (ViewHolder)convertView.getTag();
 }

 // Bind the data efficiently with the holder.
 holder.someProperty.setText( mObjects.get(position).getSomeProperty());
 ...

Эта последняя строка вызывает исключение IndexOutOfBoundsException.

Как мне справиться с такой ситуацией, когда я получаю нужные данные, не вызывая скачок списка?

1 Ответ

2 голосов
/ 07 сентября 2010

Я думаю, что предпочтительным способом является обновление самого адаптера, а не его замена. Возможно, вы можете написать метод, который объединяет новые и старые данные, используя методы адаптеров insert() и remove(). Я думаю, что это должно сохранить вашу позицию.

Добавленная информация:

Я использую следующее в качестве базовой структуры. Может быть, это поможет.


public class PlaylistAdapter extends ArrayAdapter<Playlist> {

    private ArrayList<Playlist> items;

    public PlaylistAdapter(Context context, int textViewResourceId, ArrayList<Playlist> items) {
        super(context, textViewResourceId, items);
        this.items = items;
    }

}
...