Я создаю чат-приложение для Android, подобное Hangouts. Для этого я использую вертикальный ListView с stackFromBottom=true
и transcriptMode="normal"
.
Список сортируется из более старых сообщений (вверху) в младшие сообщения (внизу). В нормальном состоянии ListView прокручивается вниз, показывая самое младшее сообщение.
В ListView используется адаптер обратной бесконечной прокрутки для загрузки более (более старых) сообщений, когда пользователь прокручивается до верхней части списка. Когда старые сообщения загружаются, они добавляются в верхнюю часть списка.
Желаемое поведение заключается в том, что ListView сохраняет свою позицию прокрутки в нижней части списка, когда старые сообщения добавляются в начало. То есть, когда старые сообщения добавляются в верхнюю часть, в представлении прокрутки должны отображаться те же сообщения, которые были показаны перед добавлением старых сообщений.
К сожалению, это не работает. Вместо того, чтобы поддерживать положение прокрутки в нижней части, ListView поддерживает положение прокрутки в верхней части списка. То есть, после добавления старых сообщений в список, список показывает самые верхние (самые старые) сообщения.
Есть ли простой способ сказать ListView сохранить свою позицию прокрутки в нижней части, а не сверху, при добавлении новых элементов в начало?
Обновление
Для демонстрационных целей я максимально минимизировал прецедент и код. В следующем примере создается простой список массивов строк. При нажатии на элемент добавляется другой элемент в верхней части списка. Длинное нажатие на элемент добавит еще один элемент в нижней части списка.
Все отлично работает при добавлении элементов в нижней части списка (длинный щелчок). При добавлении элементов вверху списка (простой щелчок), есть 3 случая:
- Если список был прокручен донизу, все работает нормально. После добавления элемента вверх, список по-прежнему прокручивается вниз.
- Если список не прокручивается снизу (ни вверху), тогда список сохранит свою позицию прокрутки (вверху). Это заставляет список "прыгать" на один предмет вверх. Я бы хотел, чтобы этот список не "прыгал" в этом случае, я бы хотел, чтобы он сохранил свою позицию прокрутки y снизу.
- Если список прокручивается вверху, то происходит то же самое, что и в случае 2. Предпочтительное поведение такое же, как в случае 2.
(Последние два случая на самом деле одинаковы. Я их отделил, потому что проблема может быть лучше продемонстрирована в случае 2.)
код
public class MyListActivity extends Activity {
int topIndex = 1;
int bottomIndex = 20;
protected final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_list_activity);
final ListView list = (ListView) findViewById(R.id.list);
list.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
list.setStackFromBottom(true);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
for (int i = topIndex; i <= bottomIndex; i++) {
adapter.add(Integer.toString(i));
}
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
adapter.insert(Integer.toString(--topIndex), 0);
}
});
list.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
adapter.add(Integer.toString(++bottomIndex));
return true;
}
});
}
}