NestedScrollView не расширяется по высоте внутри AlertDialog - PullRequest
0 голосов
/ 23 января 2020

Я в настоящее время использую представление прокрутки в диалоге оповещений, и мне нужно, чтобы представление прокрутки увеличивалось по высоте, пока диалоговое окно не достигло максимальной высоты по умолчанию. Мне сложно объяснить, поэтому я приложил иллюстрацию, чтобы помочь. Надеюсь, что это так.

enter image description here Проблема, которую я получаю, состоит в том, что представление прокрутки не увеличивается в высоте, и даже если я удаляю app:layout_constraintBottom_toTopOf="@id/linearLayout4", оно увеличивается, однако нижняя часть будет частично скрыта макетом кнопки. Это мой текущий код:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/filter_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_box"
android:minHeight="300dp"
android:elevation="12dp">

<TextView
    android:id="@+id/filter_header"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:text="@string/filter"
    style="@style/element_header"
    android:textColor="@color/textColorDark"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/filter_reset_btn"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:background="?attr/selectableItemBackgroundBorderless"
    android:text="@string/reset"
    style="@style/text_info_nBold"
    android:textSize="14sp"
    android:textColor="@color/textColorDark"
    app:layout_constraintBottom_toBottomOf="@+id/filter_header"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="@+id/filter_header" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintBottom_toTopOf="@id/linearLayout4"
    app:layout_constraintTop_toBottomOf="@id/filter_header"
    app:layout_constraintVertical_bias="0.0">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/filter_scroll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fillViewport="true"
        android:layout_marginTop="16dp"
        android:scrollbarFadeDuration="1000">

        <!-- VIEWS INSIDE HERE -->

    </androidx.core.widget.NestedScrollView>

</LinearLayout>

<LinearLayout
    android:id="@+id/linearLayout4"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog_bottombar_layout"
    android:orientation="horizontal"
    android:padding="8dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent">

    <Button
        android:id="@+id/dialog_secondary_button"
        style="@style/low_emphasis_btn"
        android:layout_width="0dp"
        android:layout_marginEnd="8dp"
        android:layout_weight="1"
        android:backgroundTint="@color/textColorDark"
        android:text="@string/dialog_cancel"
        android:textColor="@color/textColorDark"
        android:visibility="visible" />

    <Button
        android:id="@+id/dialog_primary_button"
        style="@style/high_emphasis_btn"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:text="@string/apply" />

</LinearLayout>

Любая помощь будет оценена :)

1 Ответ

2 голосов
/ 27 января 2020

Диалоговые окна предупреждений имеют тенденцию переносить содержимое или могут отображаться в полноэкранном режиме. Размер между оптимизированными экранами требует некоторой работы, но это не невозможно.

Один из подходов состоит в том, чтобы система выложила диалоговое окно с предупреждением, но перед его отображением используйте * 1003. * ViewTreeObserver.OnGlobalLayoutListener для проверки результирующего размера диалога. В слушателе макета размер диалогового окна может быть откорректирован в соответствии с содержимым прокручиваемого представления или настроен на полный экран, если содержимое прокручиваемого представления слишком велико для экрана.

Вот демонстрационная версия приложение, которое показывает, как это можно сделать. Комментарии в коде объясняют больше.

MainActivity.kt

class MainActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onClick(v: View) {
        val text = when (v.id) {
            R.id.customDialogShort -> getString(R.string.short_string)
            R.id.customDialogMedium -> getString(R.string.lorem_medium)
            else -> getString(R.string.lorem_long)
        }

        // Specifying the viewGroup as a parent to the inflater makes no difference.
        val dialogView = LayoutInflater.from(v.context).inflate(R.layout.con_custom_view, null, false) as ConstraintLayout
        (dialogView.findViewById(R.id.textView) as TextView).text = text

        val alertDialog = AlertDialog.Builder(this).setView(dialogView).create()
        val decorView = alertDialog.window!!.decorView
        decorView.setBackgroundResource(R.drawable.alert_dialog_background)

        // We need a layout pass to determine how big everything is and needs to be. Place a hook
        // at the end of the layout process to examine the layout before display.
        decorView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                decorView.viewTreeObserver.removeOnGlobalLayoutListener(this)

                // Find out how much of the scrolling view is usable by its child.
                val scrollingView: NestedScrollView = decorView.findViewById(R.id.filter_scroll)
                val scrollingViewPadding = scrollingView.paddingTop + scrollingView.paddingBottom
                val scrollingUsableHeight = scrollingView.height - scrollingViewPadding

                // If the child view fits in the scrolling view, then we are done.
                val childView = scrollingView.getChildAt(0)
                if (childView.height <= scrollingUsableHeight) {
                    return
                }

                // Child doesn't currently fit in the scrolling view. Resize the top-level
                // view so the child either fits or is forced to scroll because the maximum
                // height is reached. First, find out how much space is allowed by the decor view.
                val displayRectangle = Rect()
                decorView.getWindowVisibleDisplayFrame(displayRectangle)
                val decorViewPadding = decorView.paddingTop + decorView.paddingBottom
                val decorUsableHeight = displayRectangle.height() - decorViewPadding - scrollingViewPadding

                // Compute the height of the dialog that will 100% fit the scrolling content and
                // reduce it if it won't fit in the maximum allowed space.
                val heightToFit = dialogView.height + childView.height - scrollingUsableHeight
                dialogView.minHeight = min(decorUsableHeight, heightToFit)
            }
        })
        var buttonOk: Button = dialogView.findViewById(R.id.dialog_primary_button)
        buttonOk.setOnClickListener { alertDialog.dismiss() }
        buttonOk = dialogView.findViewById(R.id.dialog_secondary_button)
        buttonOk.setOnClickListener { alertDialog.dismiss() }
        alertDialog.show()
    }
}

activity_main. xml

<LinearLayout 
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/customDialogShort"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Short text" />

    <Button
        android:id="@+id/customDialogMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Medium text" />

    <Button
        android:id="@+id/customDialogLong"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Long text" />

</LinearLayout>

con_custom_view
Пользовательский макет для AlertDialog.

    <TextView
        android:id="@+id/filter_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="@string/filter"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/filter_reset_btn"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:text="@string/reset"
        android:textSize="14sp"
        app:layout_constraintBottom_toBottomOf="@+id/filter_header"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/filter_header" />

    <androidx.core.widget.NestedScrollView
        android:id="@+id/filter_scroll"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        android:padding="16dp"
        android:scrollbarFadeDuration="1000"
        app:layout_constraintBottom_toTopOf="@id/linearLayout4"
        app:layout_constraintTop_toBottomOf="@id/filter_header">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:text="@string/lorem_long" />

    </androidx.core.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/linearLayout4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <Button
            android:id="@+id/dialog_secondary_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_weight="1"
            android:text="@string/dialog_cancel"
            android:visibility="visible" />

        <Button
            android:id="@+id/dialog_primary_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/apply" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...