问题描述
目前,我正在尝试使我的视图的高度和宽度相对于可用空间,因此我的 ui 将更加负责。我遇到的问题是,每当我尝试在父布局中包含此布局(例如,在 fragment_shop 中包含 shop_content)时,我包含的布局的高度和宽度不再起作用。
我做了一个小例子来说明这一点。在此示例中,您可以看到工具栏的高度应为给定高度的 17%。当我在子布局中查看我的设计选项卡时,一切正常,但是在我的 fragment_shopping_cart 中导入此布局时,视图仍然不可见/高度未正确显示。
child_layout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!-- Changing this to wrap_content makes weird stuff -->
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/calibrate_btn_background"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/color_primary"
android:clickable="false"
app:layout_constraintHeight_percent="0.17" <!-- Height should take 0.17 -->
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
parent_layout
<layout
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".framework.ui.view.fragments.shop.ShoppingCartFragment">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/shopping_cart_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_primary"
app:title="@string/bottom_nav_shopping_cart"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.google.android.material.appbar.MaterialToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_shopping_cart"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.linearlayoutmanager"
app:layout_constraintBottom_toTopOf="@id/shopping_cart_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/shopping_cart_toolbar"
tools:listitem="@layout/shopping_cart_list_item" />
<include
android:id="@+id/shopping_cart_btn"
layout="@layout/child_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
它应该是什么样子
外观
我在这里做错了什么?我感谢每一个帮助。注意:我是 Android 响应式 ui 的新手
编辑
由于这个问题越来越难理解,我将尝试用这个例子更好地解释它:我有一个名为 app_standard_checkout_btn 的布局,我在我的几个布局(包括它)中使用了它。此布局包含不同的视图,例如 工具栏(用作背景)、文本视图和其他内容。
目前,工具栏的高度固定为 124dp,这就是问题所在。我不希望高度为 124dp,而是希望包含布局的整个可用高度的 0.15(在某些情况下与 124dp 相同)。这是如何实现的?
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="price"
type="Float" />
<variable
name="btnText"
type="String" />
<variable
name="btnIcon"
type="android.graphics.drawable.Drawable" />
<variable
name="btnTextCapitalized"
type="Boolean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/calibrate_btn_background"
android:layout_width="match_parent"
android:layout_height="124dp" <!-- THIS FIXED VALUE IS BAD -->
android:background="@color/color_btn_gray"
android:clickable="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/calibrate_btn_tv_sum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard8dpMargin"
android:layout_marginEnd="@dimen/big16dpMargin"
android:text="@string/calibrate_btn_price"
android:textColor="@color/color_text_dark"
android:textSize="@dimen/textHeadlinenormal2"
app:layout_constraintEnd_toStartOf="@+id/shop_item_price"
app:layout_constraintTop_toTopOf="@+id/calibrate_btn_background" />
<TextView
android:id="@+id/shop_item_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{price}"
android:textColor="@color/color_text_blue"
android:textSize="@dimen/textHeadlinenormal2"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/calibrate_btn_tv_sum"
app:layout_constraintEnd_toStartOf="@+id/calibbrate_btn_tv_intern_curr"
app:layout_constraintTop_toTopOf="@+id/calibrate_btn_tv_sum"
tools:text="4800.00" />
<TextView
android:id="@+id/calibbrate_btn_tv_intern_curr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/currency"
android:textColor="@color/color_text_blue"
android:textSize="@dimen/textHeadlinenormal2"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/shop_item_price"
app:layout_constraintEnd_toEndOf="@+id/calibrate_btn_next"
app:layout_constraintTop_toTopOf="@+id/shop_item_price" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/calibrate_btn_tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/calibrate_btn_desc"
android:textColor="@color/color_text_gray"
android:textSize="@dimen/textDescriptionnormal4"
app:layout_constraintEnd_toEndOf="@+id/calibrate_btn_next"
app:layout_constraintTop_toBottomOf="@+id/shop_item_price" />
<com.google.android.material.button.MaterialButton
android:id="@+id/calibrate_btn_next"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginStart="@dimen/big16dpMargin"
android:layout_marginEnd="@dimen/big16dpMargin"
android:layout_marginBottom="@dimen/standard8dpMargin"
android:clickable="true"
android:focusable="true"
android:text="@{btnText}"
android:textAllCaps="@{btnTextCapitalized}"
android:textSize="@dimen/textDescriptionnormal1"
android:textStyle="normal"
app:backgroundTint="@color/color_btn_blue"
app:icon="@{btnIcon}"
app:iconGravity="textStart"
app:layout_constraintBottom_toBottomOf="@id/calibrate_btn_background"
app:layout_constraintEnd_toEndOf="@id/calibrate_btn_background"
app:layout_constraintStart_toStartOf="@+id/calibrate_btn_background" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
解决方法
这一行
app:layout_constraintHeight_percent="0.17"
属于 parent_layout
,应该为 <include
标签设置或至少为 ConstraintLayout
放置在 child_layout
(文件中的根视图)
您需要将 child_layout
的顶部约束到 ReyclerView
的底部
因此向 child_layout
中添加 bleow 约束
app:layout_constraintTop_toBottomOf="@+id/rv_shopping_cart"
此更改后,整个父布局将:
<layout
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".framework.ui.view.fragments.shop.ShoppingCartFragment">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/shopping_cart_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_primary"
app:title="@string/bottom_nav_shopping_cart"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.google.android.material.appbar.MaterialToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_shopping_cart"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/shopping_cart_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/shopping_cart_toolbar"
tools:listitem="@layout/shopping_cart_list_item" />
<include
android:id="@+id/shopping_cart_btn"
layout="@layout/child_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rv_shopping_cart"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
编辑
我不希望高度为 124dp,而是希望包含布局的整个可用高度的 0.15
现在您希望 Toolbar
成为父布局的 17%,而它不是它的直接子级。这看起来很奇怪并且与 ConstraintLayout
指导不匹配因为工具栏不是父级 ConstraintLayout
因此,您不能将 Toolbar
约束到父 ConstraintLayout
;相反,您可以将整个子布局约束到父布局。因此,您需要通过硬编码或约束来限制整个子布局的高度。在不限制高度的情况下,您的共享图片中的布局会消失。
在最佳答案中,我将其约束在 RecyclerView
的底部,这就是您在与 RecyclerView
共享的 app:layout_constraintBottom_toTopOf="@id/shopping_cart_btn"
约束中所做的。这可能并不完美,因为我们无法在编译时预测 RecyclerView
的高度。
因此,这是使用 app:layout_constraintHeight_percent
约束来约束子布局相对于父布局的高度的另一种选择,就像您对其 Toolbar
所做的一样,但百分比大于 17% .由你来选择一个合适的百分比,这里我会选择 50%。
现在父级的高度是 100%。孩子的高度是 50%,因为您需要 Toolbar
的高度是父母的 17%,那么现在将它加倍到 34%。你必须根据你选择的整个子布局的值来改变它。
现在父布局将是
父布局:
<layout
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".framework.ui.view.fragments.shop.ShoppingCartFragment">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/shopping_cart_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_primary"
app:title="@string/bottom_nav_shopping_cart"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.google.android.material.appbar.MaterialToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_shopping_cart"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/shopping_cart_toolbar"
tools:listitem="@layout/shopping_cart_list_item" />
<include
android:id="@+id/shopping_cart_btn"
layout="@layout/child_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
子布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="0dp"> <!-- Changing this to wrap_content makes weird stuff -->
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/calibrate_btn_background"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/color_primary"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.34"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>