J'utilise recylerview dans mon application et chaque fois qu'un nouvel élément est ajouté à recyclerview, il défile jusqu'au dernier élément à l'aide de
recyclerView.scrollToPosition(adapter.getCount());
Cependant, chaque fois que le clavier s'ouvre (en raison de editTextView), il redimensionne la vue et la vue de recyclage devient plus petite, mais ne peut pas défiler jusqu'au dernier élément.
Android:windowSoftInputMode="adjustResize"
J'ai même essayé d'utiliser le code suivant pour faire défiler jusqu'au dernier élément, mais cela n'a pas fonctionné
editTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
recyclerView.scrollToPosition(chatAdapter.getItemCount());
}
}
});
Je peux essayer adjustPan
de déplacer le panoramique vers le haut, mais cela cache ma barre d’outils . Merci de suggérer tout moyen de rectifier le problème.
Vous pouvez récupérer les modifications apportées au clavier avec recyclerview.addOnLayoutChangeListener()
. Si bottom est inférieur à oldBottom
, le clavier est activé.
if ( bottom < oldBottom) {
recyclerview.postDelayed(new Runnable() {
@Override
public void run() {
recyclerview.scrollToPosition(bottomPosition);
}
}, 100);
}
Ajoutez ceci à votre activité ou à votre fragment:
if (Build.VERSION.SDK_INT >= 11) {
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v,
int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.smoothScrollToPosition(
recyclerView.getAdapter().getItemCount() - 1);
}
}, 100);
}
}
});
}
Ça marche pour moi
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
Bien que cette question soit ancienne, j’ai rencontré ce problème aujourd’hui et j’ai découvert qu’aucune de ces méthodes ne fonctionnait. C'est ma solution
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v,
int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) {
final int lastAdapterItem = mAdapter.getItemCount() - 1;
recyclerView.post(new Runnable() {
@Override
public void run() {
int recyclerViewPositionOffset = -1000000;
View bottomView = linearLayoutManager.findViewByPosition(lastAdapterItem);
if (bottomView != null) {
recyclerViewPositionOffset = 0 - bottomView.getHeight();
}
linearLayoutManager.scrollToPositionWithOffset(lastAdapterItem, recyclerViewPositionOffset);
}
});
}
});
}
recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());
J'ai trouvé que le postDelayed était inutile et que l'utilisation de positions d'adaptateur ne rend pas compte du fait que le recycleur est déplacé au milieu d'un élément. J'ai atteint le look que je voulais avec ça.
recycler.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, xoldRight, oldBottom) -> {
if (bottom < oldBottom) {
messageRecycler.scrollBy(0, oldBottom - bottom);
}
});
Cela marche.
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private LinearLayoutManager mManager;
...
mManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mManager);
(initialize and set adapter.)
mRecyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) scrollToBottom();
}
});
private void scrollToBottom() {
mManager.smoothScrollToPosition(mRecyclerView, null, mAdapter.getItemCount());
}
Cela fonctionne correctement dans la bibliothèque de support version 27.0.1
Il n'y a rien à définir dans le manifeste.
val currentScrollPosition = 0
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
currentScrollPosition = recyclerView.computeVerticalScrollOffset() + recyclerView.computeVerticalScrollExtent()
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { }
})
storyList.addOnLayoutChangeListener { view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
if (bottom < oldBottom) {
if (currentScrollPosition >= recyclerView.computeVerticalScrollRange()) {
recyclerVIew.post {
recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_NEVER
recyclerView.smoothScrollBy(0, recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollOffset() + recyclerView.computeVerticalScrollExtent())
}
}
} else {
recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_ALWAYS
}
}
layoutManager.scrollToPositionWithOffset (chatMessageAdapter.getItemCount () - 1, 0);
Lier le RecyclerView inside NestedScrollView
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"/>
</Android.support.v4.widget.NestedScrollView>