Превъртете RecyclerView съответно нагоре, когато се отвори клавиатурата

Създадох чат дейност и подобно на Facebook Messenger има EditText в долната част, а отгоре е RecyclerView на съобщенията. Когато клавиатурата се отвори, искам да превъртя RecyclerView нагоре точно с колко трябва да превъртя нагоре. За да бъдем по-конкретни, нека приемем, че има 5 съобщения в RecyclerView и в момента 3-то съобщение е точно над EditText. Така че, когато клавиатурата е отворена, искам да запазя 3-то съобщение точно над EditText, както преди. Търсих, но не можах да намеря. Ако това е дублиран въпрос, ще съм благодарен, ако някой може да даде линк.


person Ariful Hoque Maruf    schedule 24.11.2017    source източник
comment
Вече го пробвах, не се получи.   -  person Ariful Hoque Maruf    schedule 24.11.2017
comment
android:windowSoftInputMode=adjustPan опитайте този.   -  person mehul chauhan    schedule 24.11.2017
comment
Възможен дубликат на stackoverflow .com/questions/34102741/   -  person Hemant Parmar    schedule 24.11.2017
comment
Е, не искам да превъртам до последния елемент @HemantParmar   -  person Ariful Hoque Maruf    schedule 24.11.2017
comment
Това също не проработи @mehul   -  person Ariful Hoque Maruf    schedule 24.11.2017


Отговори (7)


recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View view, 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.scrollToPosition(adapter.getItemCount());
                    }
                }, 100);
            }
        }
    });

ако не работи Използвайте smoothScrollToPosition вместо scrollToPosition

Това е работа за мен.

person Ulagapandi UPMS    schedule 08.11.2019

Късен отговор, но може би някой ще го намери за полезен.

Ако това е приложение за чат, тогава предполагам, че искате да започнете да изграждате списъка от дъното. Например, има празен чат и след като добавите няколко съобщения, очаквате те да са в долната част на списъка. По-късно, тъй като ще има все повече и повече съобщения, по-старите съобщения ще се показват нагоре, а по-новите ще са в долната част, точно над EditText.

Ако приемем, че най-новите съобщения са първи във вашия списък/масив, можете просто да зададете LinearLayoutManager да бъде обратно оформление.

layoutManager.reverseLayout = true

Не мога да обясня защо, но изглежда, че RecyclerView винаги се опитва да запази позицията на превъртане на горната граница. Така че, когато клавиатурата се показва, наличното вертикално пространство се свива и RecyclerView просто ще се опита да запази горната си част същата, както беше преди. Като направите обратното оформление, можете да постигнете желаното поведение.

person Marat    schedule 24.12.2019

Търсих правилното решение и мисля, че го намерих.

Когато поставите вашия recyclerview вътре в ConstraintLayout, мислейки по този начин, че можете лесно да поставите вашия recyclerview правилно във връзка с другите ви изгледи (във вашия случай вашия edittext), това няма да работи.

Това беше моят xml оформление, където не работеше (имам reverseLayout=true на моя LinearLayoutManager):

<androidx.constraintlayout.widget.ConstraintLayout>

  <RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@id/editText"
    app:layout_constraintTop_toBottomOf="parent" />

  <EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

С това оформление, всеки път, когато отварях или затварях клавиатурата чрез натискане на EditText, позицията на превъртане щеше да се премести леко нагоре.

Поправих го, като не използвах ConstraintLayout, а го замених с добър стар RelativeLayout така:

<RelativeLayout>

  <RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_above="@id/editText"
    android:layout_height="match_parent" <!-- This is important, with 0dp it still doesnt work  -->
     />

  <EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

</RelativeLayout>

Когато зададете височината на RecyclerView на match_parent, това ще работи. (Причината да използваме RelativeLayout е, че на ConstraintLayout не можете да зададете layouth_height да match_parent на дъщерни изгледи, няма да функционира правилно, ако направите това.)

person Hylke    schedule 17.12.2020
comment
Имах recyclerView вътре в RelativeLayout, с 0dp височина, позиция между 2 изгледа. Странно, но настройката на височината да съответства на Parent свърши работа. (също имам набор „adjustPan“) - person DoruChidean; 26.01.2021

Имах същия проблем и не искам да задавам windowSoftInputMode на "adjustResize". Горните отговори не работят за мен.

editText.clearFocused();
hideKeyboard();

// update your adapter ... 

parent.requestLayout();

Нулирайте фокуса на родителското оформление и recylerView ще се актуализира правилно.

person Yuda    schedule 09.03.2020

Опитайте това

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.scrollToPosition(yourPosition);
person SahdevRajput74    schedule 24.11.2017

Имах същия проблем, това, което направих, е, че когато се отвори клавиатурата, превъртях recyclerView до последния елемент в recyclerView, така че никакви елементи няма да бъдат скрити. Мисля, че това е много по-лесно от начина, по който предлагаш. Така че кодът ще бъде както следва:

  recyclerView.postDelayed(new Runnable() {
            @Override
            public void run() {
                recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
            }
        }, 300);
person Sami Kanafani    schedule 24.11.2017
comment
Вече го направих. Знам, че е лесно, но не го искам. Трябва да превъртя нагоре точно както трябва да превъртя нагоре. - person Ariful Hoque Maruf; 24.11.2017

Напишете това във вашия манифест

    <activity
        android:name=".yourActivity"
        android:windowSoftInputMode="adjustResize" >
    </activity>
person SahdevRajput74    schedule 24.11.2017