CoordinatorLayout, по-видимому, имеет параметры FrameLayout

Пытаясь установить BottomSheetBehavior с соответствующим обратным вызовом для CoordinatorLayout, я наткнулся на это. При получении параметров макета указанного CoordinatorLayout вместо этого я продолжаю получать параметры FrameLayout. Это ситуация с точки зрения кода.

Из реализации BottomSheetDialogFragment

override fun setupDialog(dialog: Dialog?, style: Int) {
    super.setupDialog(dialog, style)
    val binding = DataBindingUtil.inflate<AmbientDialogBinding>(LayoutInflater.from(activity), R.layout.ambient_dialog, null, false)
    val params = activity?.findViewById<CoordinatorLayout>(R.id.homeCoordinatorLayout)?.layoutParams as CoordinatorLayout.LayoutParams
    val behaviour = params.behavior
    if (behaviour != null && behaviour is BottomSheetBehavior) {
        behaviour.setBottomSheetCallback(behaviorCallback)
    }
}

main_activity.xml

<android.support.design.widget.CoordinatorLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:id = "@+id/homeCoordinatorLayout"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:background = "@color/lightGray"
app:layout_behavior = "@string/bottom_sheet_behavior"
tools:context = ".HomeActivity">

<android.support.v7.widget.Toolbar
    android:id = "@+id/toolbar"
    android:layout_width = "match_parent"
    android:layout_height = "?attr/actionBarSize"
    android:background = "@color/colorPrimary"
    android:elevation = "4dp"
    android:theme = "@style/Base.ThemeOverlay.AppCompat.ActionBar"
    app:popupTheme = "@style/ThemeOverlay.AppCompat.Light"/>

<FrameLayout
    android:id = "@+id/container"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:layout_marginTop = "?attr/actionBarSize" />

<android.support.design.widget.FloatingActionButton
    android:id = "@+id/addAmbientButton"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:layout_gravity = "bottom|center"
    android:layout_marginBottom = "8dp"
    android:clickable = "true"
    android:focusable = "true"
    app:backgroundTint = "@color/colorPrimary"
    app:srcCompat = "@drawable/ic_add_white_24dp" />

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

fragment_dialog.xml

<android.support.v7.widget.LinearLayoutCompat
        android:id = "@+id/ambientDialogTextLayout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_marginTop = "8dp"
        android:layout_marginBottom = "8dp"
        android:orientation = "vertical">

        <EditText
            android:id = "@+id/ambientIdField"
            android:layout_width = "match_parent"
            android:layout_height = "56dp"
            android:layout_marginStart = "16dp"
            android:layout_marginEnd = "16dp"
            android:gravity = "center"
            android:hint = "Identificativo Ambiente"
            android:text = "@ = {vm.UIDLive}"
            android:textSize = "16sp" />

        <EditText
            android:id = "@+id/ambientNameField"
            android:layout_width = "match_parent"
            android:layout_height = "56dp"
            android:layout_marginTop = "16dp"
            android:layout_marginStart = "16dp"
            android:layout_marginEnd = "16dp"
            android:gravity = "center"
            android:hint = "Nome Ambiente"
            android:text = "@ = {vm.nameLive}"
            android:textSize = "16sp" />

        <android.support.design.widget.FloatingActionButton
            android:id = "@+id/confirmAmbientButton"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:layout_gravity = "bottom|center"
            android:layout_marginTop = "8dp"
            android:layout_marginBottom = "8dp"
            android:clickable = "true"
            android:focusable = "true"
            app:backgroundTint = "@color/colorPrimary"
            app:srcCompat = "@drawable/ic_check_white_24dp" />

</android.support.v7.widget.LinearLayoutCompat>

FrameLayout, который я использую в основном действии xml, используется для другого фрагмента, который, как мне кажется, не имеет никакого отношения к проблеме. Надеюсь, кто-нибудь сможет мне помочь. Заранее спасибо!

0
0
372
1

Ответы 1

Я еще не подтвердил это, но я считаю, что View, который вы передаете в setContentView() (или раздуваемое разрешение макета), добавляется в FrameLayout.

LayoutParams представления определяются его родителем, а не им. Итак, если у вас есть LinearLayout в ConstraintLayout, вызов linearLayoutInstance.layoutParams вернет экземпляр ConstraintLayout.LayoutParams.

Однако я знаю, что setContentView() добавляет ваш макет в ViewGroup. Не может быть гарантировано, что корневой макет является FrameLayout. Вы не должны приводить getParams() к корневому представлению и вместо этого полагаться на возвращаемый по умолчанию ViewGroup.LayoutParams.

Обновлено:

Вы можете увидеть список возможных раскладок здесь: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/com/android/internal/policy/PhoneWindow.java#L2541.

com.android.internal.R.content - это идентификатор корня.

Глядя на этот список и соответствующие файлы XML, можно увидеть список возможных типов корневого макета:

  • R.layout.screen_swipe_dismiss -> com.android.internal.widget.SwipeDismissLayout
  • R.layout.screen_title_icons -> FrameLayout
  • R.layout.screen_progress -> FrameLayout
  • R.layout.screen_custom_title -> FrameLayout
  • R.layout.screen_action_bar -> FrameLayout
  • R.layout.screen_title -> FrameLayout
  • R.layout.screen_simple_overlay_action_mode -> FrameLayout
  • R.layout.screen_simple -> FrameLayout

Вы даже можете определить свой собственный с помощью атрибута dialogCustomTitleDecorLayout (хотя это недоступно для приложений). Это также только из последнего исходного кода AOSP. Это может быть не так на Samsung, Huawei и т. д. Или на других версиях Android.

Извините, не могли бы вы лучше объяснить это: «Вы не должны приводить getParams () к корневому представлению, а вместо этого полагаться на возвращаемый по умолчанию ViewGroup.LayoutParams». Я не понимаю, что должен делать. Вы говорите о ViewGroup, так как я могу ссылаться на нее в setupDialog? В любом случае, большое спасибо за ответ в такой короткий срок!

Giordano 25.10.2018 22:31

Извините, неправильный синтаксис и метод. У вас layoutParams as CoordinatorLayout.LayoutParams. Удалите as CoordinatorLayout.LayoutParams.

TheWanderer 25.10.2018 22:33

Но тогда я не могу получить доступ к поведению, потому что у общего LayoutParams его нет. Должен ли я использовать метод from () из BottomSheetBehavior? Но опять же, я не думаю, что это сработает, поскольку в функции он проверяет, является ли layoutparams переданного представления CoordinatorLayout.LayoutParams

Giordano 25.10.2018 23:06

Поведение применяется к дочерним представлениям, а не к самому CoordinatorLayout.

TheWanderer 25.10.2018 23:14

Другие вопросы по теме