/ / ConstraintLayout, загорнутий у ScrollView, все ще змінюється під час відкриття клавіатури - android, android-scrollview, android-koordinatorlayout, android-constraintlayout

ConstraintLayout, зафіксований у ScrollView, все ще змінюється під час відкриття клавіатури - android, android-scrollview, android-koordinatorlayout, android-constraintlayout

Мені б хотілося відкрити клавіатуру без цьогомій розмір розміру Я не хочу використовувати налаштуванняNothing, тому що мені потрібен один із моїх нижчих поглядів, щоб підняти клавіатуру. Я також вважаю за краще не використовувати налаштуванняPan, тому що це підвищує всю компоновку екрана, який є своєрідним потворний.

Отже, я загорнув свій макет (ConstraintLayout) у ScrollView так:

<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
<variable
name="viewModel"
type="com.mypackage.MyViewModel"/>
</data>

<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">

<!-- I don"t want anything in this ConstraintLayout to move or resize when I open the keyboard, hence why I wrapped it in a ScrollView. -->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
android:id="@+id/scene_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<ImageView
android:id="@+id/scene"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"
android:background="@color/black"
android:scaleType="fitCenter"
android:src="@drawable/grumpy"/>
</FrameLayout>

<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".7"/>

<View
android:id="@+id/status_bar"
android:layout_width="0dp"
android:layout_height="48dp"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/guideline"/>

<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="48dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/status_bar"/>

</android.support.constraint.ConstraintLayout>

</ScrollView>

<!-- The bottom sheet contains a 48dp high peekable area (a bar with an EditText) that I need to raise with the keyboard. -->
<include
android:id="@+id/bottom_sheet"
layout="@layout/bottom_sheet"
app:viewModel="@{viewModel}"/>

</android.support.design.widget.CoordinatorLayout>

Це добре працює перші два рази, коли я піднімаю клавіатуру. Ось проблема, яка у мене є. Кожен ТРЕТІ Коли я піднімаю клавіатуру, мій розмір змінюється і стискається, як ніби ScrollView не є навіть там. Це відбувається постійно ТРЕТІ час я відкриваю клавіатуру так:

1) Open keyboard. Layout remains same size.
Close keyboard.
2) Open keyboard. Layout remains same size.
Close keyboard.
3) Open keyboard. *LAYOUT RESIZES/SQUISHES TOGETHER!*
Close keyboard.

The above cycle repeats as I continue to open/close the keyboard.

Будь-які ідеї, як це вирішити? Чому макет змінює розмір кожного третього разу, коли я відкриваю клавіатуру?

Відповіді:

2 для відповіді № 1

Насправді, якщо ви користуєтесь match_parent як розмір ScrollView дитина, вона також змінить розмір, коли клавіатура з'явиться і помістить ScrollView розмір

Щоб зрозуміти як ScrollView робота, ви можете подумати про браузер. На кожному перехідному посиланні, якщо сторінка не відповідає вікнам браузера, ви побачите смугу прокрутки, яка дозволить вам переходити по цій сторінці. ScrollView ті ж самі, вам просто потрібно надати їм розмір, який ви хочете займати на екрані (як вікно браузера), і ви можете помістити все в нього (наприклад, сторінку веб-сайту), навіть якщо він більший за ScrollView розмір

Відповідно до цього, ваш ConstraintLayout потрібен фіксований розмір. Це може бути wrap_content якщо ви хочете, щоб користувач отримав доступ до всіх компонентів у ньому. Це не ваш випадок. Ви хочете, щоб він зберігав свій початковий розмір, тобто, як я бачу у вашому коді, також розмір вашого першого CoordinatorLayout.

Єдиний спосіб я знайшов виправити внутрішнє ConstraintLayout до вихідного розміру подання - за кодом.

Давайте "s спростить ваш xml для прикладу:

<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:id="@+id/parentView"
android:layout_height="match_parent">

<ScrollView
android:id="@+id/scrollViewItem"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.constraint.ConstraintLayout
android:id="@+id/childView"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<!--ALL YOUR ITEMS-->

</android.support.constraint.ConstraintLayout>

</ScrollView>

</android.support.design.widget.CoordinatorLayout>

Вам потрібно виправити розмір childView при завантаженні екрана. На onCreate, ви можете додати цей код:

private int first = 0;

public class ConstaintLayoutCanScroll extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

first = childView.getMeasuredHeight();

final CoordinatorLayout parentView = findViewById(R.id.parentView);
parentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (first < parentView.getMeasuredHeight()) {
ConstraintLayout childView = findViewById(R.id.childView);
childView.setMinHeight(parentView.getMeasuredHeight());
first = childView.getMeasuredHeight();
}
return true;
}
});

}

}

Я використовую слухача, оскільки в OnCreate, розмір ще не init. first є тому, що onPreDraw не називається андроїд лише один раз. Це змінна категорія, яку я за замовчуванням фіксую до 0.


0 для відповіді № 2

Використовуючи match_parent як розмір ScrollView дитина не ідеальна. Ви повинні скористатися фіксованим розміром або wrap_content. У вашій поточній установці ConstraintLayout намагається встановити свою висоту на ScrollView"s висота, і це змінюється залежно від відображення клавіатури чи ні.

Ви можете спробувати встановити своє ConstraintLayout до фіксованої висоти, як тільки вона відобразиться на екрані.

Щоб перевірити, чи працює такий підхід, ви можете спробувати встановити, наприклад, android:layout_height="400dp" на тобі ConstraintLayout і подивіться, відбудеться чи ні, "згаданий вами" цикл відбуватиметься чи ні. Якщо це працює, ви можете перейти до використання реального виміру ConstraintLayout відповідність розміру екрана.