Я пытаюсь использовать RecyclerView
для создания приложения чата. Я использую LinearLayoutManager
с setReverseLayout(true)
.
Когда я прокручиваюсь до конца (это начало набора данных = новое сообщение), и новое сообщение вставляется в набор данных, элемент отображается в нижней части списка, как и ожидалось (просмотр прокручивается вверх чтобы освободить место для нового предмета).
Проблема у меня есть, когда я прокручиваю вверх, чтобы увидеть старые сообщения. Когда новое сообщение вставлено в начало набора данных, представление прокручивается примерно на одну высоту сообщения, даже если это сообщение даже не отображается, поскольку оно выходит за пределы области просмотра.
Как сохранить поведение прокрутки, когда представление прокручивается вниз, но отключите его, когда я прокрутил старые сообщения?
UPDATE: Я также сделал небольшое приложение, в котором эта проблема воспроизводится: https://github.com/ehehhh/RecyclerViewProblem
ОБНОВЛЕНИЕ 2: Я совершил исправление, которое сработало и с репо, которое я сделал.
Соответствующий код (надеюсь):
compile 'com.android.support:recyclerview-v7:24.2.0'
XML:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="8dp"
android:paddingTop="8dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
Код инициализации RecyclerView:
layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setScrollContainer(true);
recyclerView.setLayoutAnimation(null);
recyclerView.setItemAnimator(null);
adapter = new ChatAdapter(...);
recyclerView.setAdapter(adapter);
Adapter:
public class ChatAdapter extends RecyclerView.Adapter<ChatViewHolder> {
private List<MessageWrapper> dataset;
public ChatAdapter(List<MessageWrapper> dataset, ...) {
this.dataset = dataset;
setHasStableIds(true);
}
...
@Override
public long getItemId(int position) {
return dataset.get(position).getId();
}
@Override
public int getItemCount() {
return dataset.size();
}
public void datasetChanged(List<MessageWrapper> dataset) {
this.dataset = dataset;
notifyDataSetChanged();
}
}
Когда новый элемент добавляется в набор данных, я просто вызываю метод datasetChanged
в адаптере.