web-dev-qa-db-fra.com

La vue de recyclage ne finit pas par défiler à l'ouverture du clavier

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.

42
Mukesh Sharma

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);
}
55
jihoon kim

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);
                }
            }
        });
    }
41
mutkan

Ça marche pour moi

LinearLayoutManager layoutManager = new LinearLayoutManager(context);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
15
anisart

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);
                  }
                });
              }
         });
   }
7
Kutae Shaw
        recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());
3
sdelvalle57

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);
    }
});
3
mp501

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

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
        }
    }
1
minjung Ahn

layoutManager.scrollToPositionWithOffset (chatMessageAdapter.getItemCount () - 1, 0);

0
Ramesh R

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>
0
Karthikeyan