Създадох чат дейност и подобно на Facebook Messenger има EditText в долната част, а отгоре е RecyclerView на съобщенията. Когато клавиатурата се отвори, искам да превъртя RecyclerView нагоре точно с колко трябва да превъртя нагоре. За да бъдем по-конкретни, нека приемем, че има 5 съобщения в RecyclerView и в момента 3-то съобщение е точно над EditText. Така че, когато клавиатурата е отворена, искам да запазя 3-то съобщение точно над EditText, както преди. Търсих, но не можах да намеря. Ако това е дублиран въпрос, ще съм благодарен, ако някой може да даде линк.
Превъртете RecyclerView съответно нагоре, когато се отвори клавиатурата
Отговори (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
Това е работа за мен.
Късен отговор, но може би някой ще го намери за полезен.
Ако това е приложение за чат, тогава предполагам, че искате да започнете да изграждате списъка от дъното. Например, има празен чат и след като добавите няколко съобщения, очаквате те да са в долната част на списъка. По-късно, тъй като ще има все повече и повече съобщения, по-старите съобщения ще се показват нагоре, а по-новите ще са в долната част, точно над EditText
.
Ако приемем, че най-новите съобщения са първи във вашия списък/масив, можете просто да зададете LinearLayoutManager
да бъде обратно оформление.
layoutManager.reverseLayout = true
Не мога да обясня защо, но изглежда, че RecyclerView
винаги се опитва да запази позицията на превъртане на горната граница. Така че, когато клавиатурата се показва, наличното вертикално пространство се свива и RecyclerView
просто ще се опита да запази горната си част същата, както беше преди. Като направите обратното оформление, можете да постигнете желаното поведение.
Търсих правилното решение и мисля, че го намерих.
Когато поставите вашия 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 на дъщерни изгледи, няма да функционира правилно, ако направите това.)
Имах същия проблем и не искам да задавам windowSoftInputMode на "adjustResize". Горните отговори не работят за мен.
editText.clearFocused();
hideKeyboard();
// update your adapter ...
parent.requestLayout();
Нулирайте фокуса на родителското оформление и recylerView ще се актуализира правилно.
Опитайте това
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.scrollToPosition(yourPosition);
Имах същия проблем, това, което направих, е, че когато се отвори клавиатурата, превъртях recyclerView до последния елемент в recyclerView, така че никакви елементи няма да бъдат скрити. Мисля, че това е много по-лесно от начина, по който предлагаш. Така че кодът ще бъде както следва:
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
}
}, 300);
Напишете това във вашия манифест
<activity
android:name=".yourActivity"
android:windowSoftInputMode="adjustResize" >
</activity>