【问题标题】:ConstraintLayout: Why does the height of a view affect its children?ConstraintLayout:为什么视图的高度会影响其子项?
【发布时间】:2019-12-23 10:05:18
【问题描述】:

我正在 Android Studio 中构建一个应用程序并遇到问题,我不知道为什么会发生以及如何解决它。这是我的代码:

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"

android:background="#f4f4f4"
tools:context=".MainActivity">

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="144dp"
android:gravity="center"
android:shadowColor="#000000"
android:text="@string/title"
android:textColor="#eadca6"
android:textSize="60sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.500"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />

<Button
android:id="@+id/button"
android:layout_width="342dp"
android:layout_height="0dp"
android:layout_marginStart="160dp"
android:layout_marginLeft="160dp"
android:layout_marginTop="260dp"
android:layout_marginEnd="160dp"
android:layout_marginRight="160dp"
android:background="#eadca6"
android:text="@string/all_quotes"
android:textAllCaps="false"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.500"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />

<Button
android:id="@+id/button2"
android:layout_width="342dp"
android:layout_height="0dp"
android:layout_marginStart="160dp"
android:layout_marginLeft="160dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="160dp"
android:layout_marginRight="160dp"
android:layout_marginBottom="50dp"
android:background="#eadca6"
android:text="@string/favorite_quotes"
android:textAllCaps="false"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.500"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>

但是,如果你像这样运行代码,标题会被剪掉一半。但是 2 个按钮将具有正常大小。如果我在 textview 上使用 wrap_content,TextView 将正常显示,但按钮高度也只会与里面的文本一样大(如继承换行内容),即使我没有在按钮字段中编写 wrap_content。 LayoutEditor 告诉我一切都很好,但是当我运行应用程序时,那些设计“错误”就会发生。

【问题讨论】:

    标签: java android xml android-layout android-constraintlayout


    【解决方案1】:

    我在您的代码中添加了一些修改并为此代码添加了屏幕截图

    <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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f4f4f4"
    tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="144dp"
        android:shadowColor="#000000"
        android:text="title"
        android:textAlignment="center"
        android:textColor="#eadca6"
        android:textSize="60sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.500"
        app:layout_constraintVertical_bias="0.0" />
    
    <Button
        android:id="@+id/button"
        android:layout_width="342dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="260dp"
        android:layout_marginLeft="35dp"
        android:layout_marginRight="35dp"
        android:background="#eadca6"
        android:text="all_quotes"
        android:textAllCaps="false"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
    
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:layout_marginTop="23dp"
        android:layout_marginBottom="50dp"
        android:layout_marginLeft="35dp"
        android:layout_marginRight="35dp"
        android:background="#eadca6"
        android:text="favqussdi"
        android:textAllCaps="false"
        android:textSize="20sp"
        app:layout_constraintTop_toBottomOf="@+id/button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
    

    如您所见,我更改了以下内容:

    1. android:layout_height change 值变成wrap_content;
    2. android:layout_width change 值变成match_parent;
    3. 在按钮中添加了android:paddingTop="10dp"android:paddingBottom="10dp"
    4. 修改layout_marginLeftlayout_marginRight

    去掉一些冗余代码,也尽量避免添加静态数字。希望对你有所帮助^^

    【讨论】:

    • +1 对我来说,但是您的回答不会使布局响应。您可以查看我的答案以了解具体方法。
    【解决方案2】:

    你想知道你的代码有什么问题,所以我会在编写代码之前先解释一下:

    TL;DR:

    不要在视图上使用固定大小,您可以使用 app:layout_constraintHeight_percent="0.xx"app:layout_constraintWidth_percent="0.yy"Guidelines


    完整答案

    不同的手机有不同的屏幕尺寸,在您的布局中,您在视图上使用了固定尺寸(例如,固定尺寸为 android:layout_marginTop="144dp"),结果是在一个屏幕上看起来不错屏幕(您的 android studio 预览屏幕)在另一个屏幕(您的实际手机)上看起来不太好,这就是您收到设计“错误”的原因。

    在使用wrap_content 时,您也不能保证完全的布局责任,例如,如果您将拍摄一张非常大的图像并将其放在您的视图中,它在不同设备上的外观不会相同。


    如果您已经在使用constraintLayout,这里有一些工具可以帮助您实现适合所有屏幕尺寸的响应式布局。

    例如,看看这个布局:

    <?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"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="#f4f4f4"
      tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:gravity="center"
        android:shadowColor="#000000"
        android:text="title"
        android:textColor="#eadca6"
        android:textSize="60sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/guideline3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.15"
        app:layout_constraintWidth_percent="0.9"
        app:layout_constraintStart_toStartOf="parent" />
    
    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#eadca6"
        android:text="all_quotes"
        android:textAllCaps="false"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/guideline2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.500"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintWidth_percent="0.9" />
    
    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#eadca6"
        android:text="favorite_quotes"
        android:textAllCaps="false"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button"
        app:layout_constraintWidth_percent="0.9" />
    
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.8" />
    
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.2" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    此布局将如下所示:


    我在这个布局中做了什么:

    我摆脱了视图上的每一个固定大小,并给了它们固定大小,就像视图上这样的东西:

        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintHeight_percent="0.15" 
        app:layout_constraintWidth_percent="0.9"
    

    此视图的大小将等于屏幕高度的 15% 和宽度的 90%,它将响应不同的布局。

    我使用Guidelines管理视图的位置,例如:

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.2" />
    

    此指南将放置在屏幕的顶部 20%。

    一些额外的东西 - 如果你想缩放视图的大小,可以使用 ssp / sdp(在你的情况下,我会使用 ssp 库来缩放视图上的文本大小)。

    【讨论】:

    • 非常感谢!请问初学者如何学习这个?比如,你有什么建议吗?
    • 首先创建一个布局,关注ConstraintLayout页面,并询问更多关于堆栈溢出的问题
    【解决方案3】:

    在您的 xml 中尝试此代码。这样按钮和文本就会看起来很正常。

    <?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    
        android:background="#f4f4f4"
        tools:context=".MainActivity">
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:shadowColor="#000000"
            android:text="@string/title"
            android:textColor="#eadca6"
            android:textSize="60sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/group"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    
        <Button
            android:id="@+id/button"
            android:layout_width="342dp"
            android:layout_height="120dp"
            android:background="#eadca6"
            android:text="@string/all_quotes"
            android:textAllCaps="false"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/button2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@id/group" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="342dp"
            android:layout_height="120dp"
            android:layout_marginTop="20dp"
            android:background="#eadca6"
            android:text="@string/favorite_quotes"
            android:textAllCaps="false"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="@id/group"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button" />
    
        <androidx.constraintlayout.widget.Group
            android:id="@+id/group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:constraint_referenced_ids="button,button2"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    【讨论】:

    • 您好,感谢您的回答。但我需要了解为什么我的代码不起作用以及您的解决方案为何起作用。
    • 您的代码不起作用,因为 TextView 和 Buttons 的 layout_marginTop 和 layout_marginBottom 太大。因此,内容不适合屏幕,TextView 和 Buttons 的内容被裁剪。例如,如果您对 TextView 使用 android:layout_marginTop="120dp" - 内容将不会被裁剪。
    • 通常当你创建一个布局时,你设置你知道的项目的大小(对于TextView的宽度和高度是wrap_content,对于Button - 静态高度和宽度),所有其他的东西都应该一样灵活尽可能(设置这么多的静态边距是不好的做法)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2020-01-07
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多