Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recyclerview not scrolling to end when keyboard opens

I am using recylerview in my application and whenever new element is added to recyclerview, it scrolls to last element by using

recyclerView.scrollToPosition(adapter.getCount());

But, whenever keyboard opens(because of editTextView), it resizes the view and recyclerview gets smaller, but couldn't scroll to last element.

android:windowSoftInputMode="adjustResize"

I even tried to used the following code to scroll to last element, but it didn't work

editTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus){
                recyclerView.scrollToPosition(chatAdapter.getItemCount());
            }
        }
    });

I can try adjustPan to shift the pan up, but it is hiding my toolbar. Please suggest any way to rectify the issue.

like image 343
Mukesh Sharma Avatar asked Dec 05 '15 08:12

Mukesh Sharma


4 Answers

You can catch keyboard up changes using recyclerview.addOnLayoutChangeListener(). If bottom is smaller than oldBottom then keyboard is in up state.

if ( bottom < oldBottom) { 
   recyclerview.postDelayed(new Runnable() { 
       @Override 
       public void run() {
           recyclerview.smoothScrollToPosition(bottomPosition); 
       }
    }, 100);
}
like image 124
jihoon kim Avatar answered Nov 12 '22 23:11

jihoon kim


Add this your activity or 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);
                }
            }
        });
    }
like image 41
mutkan Avatar answered Nov 12 '22 23:11

mutkan


It works for me

LinearLayoutManager layoutManager = new LinearLayoutManager(context);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
like image 37
anisart Avatar answered Nov 12 '22 23:11

anisart


I found the postDelayed to be unnecessary and using adapter positions doesn't account for when the recycler is scrolled to somewhere in the middle of an item. I achieved the look I wanted with this:

recycler.addOnLayoutChangeListener((view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
    if (bottom < oldBottom) {
        messageRecycler.scrollBy(0, oldBottom - bottom);
    }
})
like image 14
mp501 Avatar answered Nov 12 '22 21:11

mp501