with recyclerview android android-recyclerview chat reverse linearlayoutmanager

android - recyclerview with header



RecyclerView scrolling on insert (2)

Estoy tratando de usar RecyclerView para crear una aplicación de chat. Estoy usando un LinearLayoutManager con setReverseLayout(true) .

Cuando me desplazo hasta la parte inferior (que es el inicio del conjunto de datos = mensaje más nuevo) y se inserta un nuevo mensaje en el conjunto de datos, el elemento aparece en la parte inferior de la lista como se esperaba (la vista se desplaza hacia arriba para hacer espacio) para el nuevo artículo).

El problema que tengo es cuando me he desplazado hacia arriba para ver los mensajes anteriores. Cuando se inserta un nuevo mensaje al principio del conjunto de datos, la vista se desplaza hacia arriba aproximadamente en una altura de mensaje, aunque ese mensaje ni siquiera se haya procesado, ya que está fuera del rango de la ventana gráfica.

¿Cómo puedo mantener el comportamiento de desplazamiento cuando la vista se desplaza hacia la parte inferior, pero deshabilitarla cuando me he desplazado a los mensajes más antiguos?

ACTUALIZACIÓN: También hice una aplicación pequeña, donde se reproduce este problema: https://github.com/ehehhh/RecyclerViewProblem

ACTUALIZACIÓN 2: También comprometí la solución que funcionó en el repositorio que hice.

Código relevante (con suerte ):

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"/>

Código de inicio de 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);

Adaptador :

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

Cuando se agrega un nuevo elemento al conjunto de datos, solo llamo al método datasetChanged en el adaptador.


Tuve un problema similar Estaba creando una aplicación de chat, y mi RecyclerView siempre mostraba filas desde la parte superior, y quería ir a la parte inferior para mostrar el último mensaje insertado. Esto es lo que funcionó para mí, recyclerView.scrollToPosition(messages.size()-1) agregado en ChildEventListener :

public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private MessageAdapter mMessageAdapter; private List<Message> messages; private FirebaseDatabase mFirebaseDatabase; private DatabaseReference mMessagesDatabaseRef; .... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFirebaseDatabase = FirebaseDatabase.getInstance(); mMessagesDatabaseRef = mFirebaseDatabase.getReference().child("messages"); recyclerView = (RecyclerView) findViewById(R.id.recycler_view); // Initialize message ListView and its adapter messages = new ArrayList<>(); mMessageAdapter = new MessageAdapter(messages); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext()); recyclerView.setLayoutManager(mLayoutManager); recyclerView.setAdapter(mMessageAdapter); ..... mMessagesDatabaseRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { messages.add(dataSnapshot.getValue(Message.class)); recyclerView.scrollToPosition(messages.size()-1); mMessageAdapter.notifyDataSetChanged(); } ...... }); } }