如何将 Android 中的布局大小设置为屏幕大小的百分比

How to set size of layouts in Android as a percentage of the sceen size

我在 Android 中有一个带有内部 ConstraintLayout 和内部线性布局的 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:id="@+id/outerConstraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_marginTop="@dimen/_5sdp"
        android:layout_marginBottom="@dimen/_8sdp"
        android:layout_width="@dimen/_235sdp"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:background="@drawable/rim"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.93"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.75">

    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/innerConstraintLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
        app:layout_constraintEnd_toStartOf="@+id/linearLayout"
        android:layout_marginLeft="@dimen/_10sdp"
        android:layout_marginRight="@dimen/_30sdp"
        android:background="@drawable/rim"
        android:padding="12dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/linearLayout"
        >

        <TextView
            android:id="@+id/textView_Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Inner Constrained Layout"
            android:textColor="#000000"
            android:textSize="@dimen/_10ssp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button_okay"
            android:layout_width="match_parent"
            android:layout_height="@dimen/_25sdp"
            android:background="@color/colorGreen"
            android:text="Okay"
            android:textAllCaps="false"
            android:textColor="#121212"
            android:textSize="@dimen/_8ssp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.553"
            app:layout_constraintStart_toStartOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

问题是两种布局在不同屏幕显示时比例不同(见截图):

这看起来不太好,因为根据使用的设备,布局在比例(宽度和高度)方面看起来非常不同。现在我的问题是是否有一种方法可以将布局的宽度和高度通常设置为屏幕尺寸的百分比,从而使布局的宽度和高度的比例与屏幕尺寸无关?或者您将如何设计布局,使其宽度和高度之间的比例或多或少与屏幕尺寸无关?

我会感谢每条评论,如果你能分享你在该问题上的经验,我会很高兴?

我遇到了几乎相同的问题,为了解决这个问题,我将每一层分为两种模式(手机和平板电脑)(Android系统本身可以识别尺寸)并扩展两者。 这样,我的工作更有规律,接下来的模式变化对我来说也很容易。

我的解决方案:

像这样制作你的资源。

分辨率/布局/my_layout.xml

layout for normal screen size ("default")

res/layout-large/my_layout.xml

layout for large screen size

如果您不知道如何创建布局大文件夹,您所要做的就是在 Project Explorer 路径中创建一个同名文件夹,并将您的层放在那里。 然后 Android 本身将自动放置在 Android Studio Live 文件夹中的每个图层的单独文件夹中。 例如activity_main文件夹包含两层如下图

首先简化视图树。使用虚拟布局而不是嵌套。您可以使用 GuidelineFlow、属性 app:layout_constraintDimensionRatio 或带有权重的链,以便 ConstraintLayout 的子项使用所需的比例。 这个article可能对你有帮助

另一种方法是创建不同的layout with qualifiers。为了更好的设计管理,最好使用单一布局。

<LinearLayout
        ...
        android:layout_width="@dimen/_235sdp"
        ...
>

我假设在 @dimen/_235sdp 中您的值为 235dp。如果是这样,该行会在所有设备上为您的 LinearLayout 固定宽度 235dp,因此您不能期望它按百分比缩放。

尝试使用具有百分比值的垂直 Guideline 并删除所有其他固定尺寸:

<?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:id="@+id/outerConstraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3"/>

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_marginTop="@dimen/_5sdp"
        android:layout_marginBottom="@dimen/_8sdp"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:background="@android:color/holo_red_dark"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/guideline"
        app:layout_constraintEnd_toEndOf="parent">

    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/innerConstraintLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="@dimen/_10sdp"
        android:layout_marginEnd="@dimen/_30sdp"
        android:background="@android:color/holo_blue_dark"
        android:padding="12dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/guideline">

        <TextView
            android:id="@+id/textView_Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Inner Constrained Layout"
            android:textColor="#000000"
            android:textSize="@dimen/_10ssp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button_okay"
            android:layout_width="match_parent"
            android:layout_height="@dimen/_25sdp"
            android:background="@android:color/holo_green_light"
            android:text="Okay"
            android:textAllCaps="false"
            android:textColor="#121212"
            android:textSize="@dimen/_8ssp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

在更新的代码中,我添加了一条垂直参考线,将屏幕分为 0.3 和 0.7,然后我根据该参考线限制内部布局以保持比例。现在在任何设备上,您应该看到左侧内部布局始终占用宽度的 0.3,右侧内部布局始终占用宽度的 0.7。

提示:尽量避免在 ConstraintLayout 中使用 ConstraintLayout,应该完全可以在不破坏布局的情况下将内部内容(即 TextView、Button)约束到父级 ConstraintLayout

现在我的问题是是否有一种方法可以将布局的宽度和高度通常设置为屏幕尺寸的百分比

可以像这样使用 constarintLayout 来完成:

  • 采取任何观点,给它 android:layout_height="0dp" - 现在它会尊重你的约束,另外添加到它 app:layout_constraintHeight_percent="0.15"

现在视图的高度是父尺寸的 15%。

  • 宽度也可以这样做android:layout_width="0dp"app:layout_constraintWidth_percent="0.5" 一起,现在您的视图将占据父级大小的 50%。

您可以像这样组合这 2 个:

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

现在您的视图是父级宽度的 15% 和父级高度的 50%,更改这些数字,您可以根据需要控制视图大小。