RelativeLayout中的百分比宽度

Sar*_*son 437 android android-layout android-relativelayout

我正在为Activity我的Android应用程序中的登录工作.下面的图片是我希望它看起来像:

在此输入图像描述

我能够使用以下XML实现此布局.问题是,它有点hackish.我不得不为主机EditText硬编码宽度.具体来说,我必须指定:

android:layout_width="172dp" 
Run Code Online (Sandbox Code Playgroud)

我真的想给主机和端口EditText提供一个百分比宽度.(主机为80%,端口为20%.)这可能吗?以下XML适用于我的Droid,但似乎并不适用于所有屏幕.我真的想要一个更强大的解决方案.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:id="@+id/host_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/home"
        android:paddingLeft="15dp"
        android:paddingTop="0dp"
        android:text="host"
        android:textColor="#a5d4e2"
        android:textSize="25sp"
        android:textStyle="normal" />

    <TextView
        android:id="@+id/port_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/home"
        android:layout_toRightOf="@+id/host_input"
        android:paddingTop="0dp"
        android:text="port"
        android:textColor="#a5d4e2"
        android:textSize="25sp"
        android:textStyle="normal" />

    <EditText
        android:id="@+id/host_input"
        android:layout_width="172dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/host_label"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_marginTop="4dp"
        android:background="@android:drawable/editbox_background"
        android:inputType="textEmailAddress" />

    <EditText
        android:id="@+id/port_input"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/host_label"
        android:layout_marginTop="4dp"
        android:layout_toRightOf="@id/host_input"
        android:background="@android:drawable/editbox_background"
        android:inputType="number" />

    <TextView
        android:id="@+id/username_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/host_input"
        android:paddingLeft="15dp"
        android:paddingTop="15dp"
        android:text="username"
        android:textColor="#a5d4e2"
        android:textSize="25sp"
        android:textStyle="normal" />

    <EditText
        android:id="@+id/username_input"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/username_label"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_marginTop="4dp"
        android:background="@android:drawable/editbox_background"
        android:inputType="textEmailAddress" />

    <TextView
        android:id="@+id/password_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/username_input"
        android:paddingLeft="15dp"
        android:paddingTop="15dp"
        android:text="password"
        android:textColor="#a5d4e2"
        android:textSize="25sp"
        android:textStyle="normal" />

    <EditText
        android:id="@+id/password_input"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/password_label"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_marginTop="4dp"
        android:background="@android:drawable/editbox_background"
        android:inputType="textPassword" />

    <ImageView
        android:id="@+id/home"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="false"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="15dp"
        android:scaleType="fitStart"
        android:src="@drawable/home" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password_input"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp"
        android:text="   login   "
        android:textSize="18sp" >
    </Button>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

Dal*_*mas 740

您正在寻找android:layout_weight属性.它允许您使用百分比来定义布局.

在以下示例中,左按钮使用70%的空间,右按钮使用30%.

<LinearLayout
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:text="left" 
        android:layout_width="0dp" 
        android:layout_height="wrap_content" 
        android:layout_weight=".70" /> 

    <Button
        android:text="right" 
        android:layout_width="0dp" 
        android:layout_height="wrap_content" 
        android:layout_weight=".30" />

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

它适用于任何类型的View,您可以使用一些EditText替换按钮以满足您的需求.

请确保设置layout_width0dp或您的视图可能无法正确缩放.

请注意,权重总和不必等于1,我发现这样更容易阅读.您可以将第一个权重设置为7,将第二个权重设置为3,它将得到相同的结果.

  • 这对于使用LinearLayout是有意义的,但他想要一个RelativeLayout.有没有办法这样做,因为我需要使用RelativeLayout为List项 (170认同)
  • 是的,在RelativeLayout中创建一个嵌套的LinearLayout,您可以在其中使用百分比. (32认同)
  • 只有当我将宽度设置为0px时,LadaRaider给出的答案才适合我.机器人:layout_width = "0像素" (17认同)
  • 这个答案非常有效,但是如果您已经开始使用RelativeLayout,那么现在可以使用支持库中的[PercentRelativeLayout](https://developer.android.com/reference/android/support/percent/PercentRelativeLayout.html)版本23.0.0. (13认同)
  • 或者只是一个View而不是Button.更明显的是它没有那样做. (6认同)

ole*_*vre 289

这并没有完全回答原始问题,即70/30分割,但在组件之间有50/50分割的特殊情况下,有一种方法:在中心放置一个看不见的支柱并用它来定位两个感兴趣的组件.

<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <View android:id="@+id/strut"
        android:layout_width="0dp"
        android:layout_height="0dp" 
        android:layout_centerHorizontal="true"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/strut"
        android:layout_alignParentLeft="true"
        android:text="Left"/> 
    <Button 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/strut"
        android:layout_alignParentRight="true"
        android:text="Right"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

由于这是一个非常常见的情况,这个解决方案不仅仅是一种好奇心.这是一个黑客但有效的一个,因为空的,零大小的支柱应该花费很少.

但总的来说,最好不要对Android布局中存在太多期待......

  • 为什么我们需要一个解决方法就是我想知道的.这是HTML的基本和长期功能.当然,Android开发人员可以查看HTML以了解人们将需要和使用的内容! (19认同)
  • 您甚至可以在strut上指定`android:visibility ="invisible"`来跳过onDraw调用;) (16认同)
  • 我真的很喜欢这个主意!我非常喜欢RelativeLayout,这是我避免使用TableLayout的另一个原因.谢谢!:) (8认同)
  • @JohnK完全同意.html/css比android布局系统好多很多. (2认同)

N J*_*N J 133

更新1

正如指出的@EmJiHash PercentRelativeLayout 中弃用 API级别26.0.0

以下引用谷歌评论:

此类在API级别26.0.0中已弃用.考虑使用ConstraintLayout和相关的布局.以下显示如何使用ConstraintLayout复制百分比布局的功能


谷歌推出了名为 android.support.percent的新API

然后,您只需指定要查看的百分比即可

添加编译依赖性就像

implementation 'com.android.support:percent:22.2.0
Run Code Online (Sandbox Code Playgroud)

在那里,PercentRelativeLayout是我们可以做百分比明智的布局

 <android.support.percent.PercentRelativeLayout
     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">
     <ImageView
         app:layout_widthPercent="50%"
         app:layout_heightPercent="50%"
         app:layout_marginTopPercent="25%"
         app:layout_marginLeftPercent="25%"/>
 </android.support.percent.PercentRelativeLayout>
Run Code Online (Sandbox Code Playgroud)

  • 如果你想将它用于listview项目,它将无法正常工作 (4认同)
  • 此类在 API 级别 26.0.0-beta1 中已弃用。考虑使用 ConstraintLayout 和关联布局 (2认同)

Rom*_*Guy 79

您不能使用百分比来定义RelativeLayout中View的尺寸.最好的方法是使用LinearLayout和权重,或自定义布局.

  • 是时候更新你的答案,你是这里选择的:) (14认同)

gbe*_*ero 31

您可以查看新的百分比支持库.

compile 'com.android.support:percent:22.2.0'
Run Code Online (Sandbox Code Playgroud)

文档

样品

  • 此类在 API 级别 26.0.0-beta1 中已弃用。考虑使用 ConstraintLayout 和关联的布局。 (2认同)

Int*_*iya 19

您可以使用PercentRelativeLayout,它是设计支持库中最近未记录的附加内容,使您不仅可以指定彼此相对的元素,还可以指定可用空间的总百分比.

RelativeLayout的子类,支持基于百分比的维度和边距.您可以使用带有"Percent"后缀的属性来指定子项的维度或边距.

<android.support.percent.PercentRelativeLayout
     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">
  <ImageView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_widthPercent="50%"
      app:layout_heightPercent="50%"
      app:layout_marginTopPercent="25%"
      app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentFrameLayout>
Run Code Online (Sandbox Code Playgroud)

Percent包提供API以支持在应用中添加和管理基于百分比的维度.

要使用,您需要将此添加到Gradle依赖关系列表中:

dependencies {
    compile 'com.android.support:percent:22.2.0'//23.1.1
}
Run Code Online (Sandbox Code Playgroud)

  • 仍然需要定义 `android:layout_width="match_parent"` (2认同)

小智 11

我已经解决了这个创建自定义视图:

public class FractionalSizeView extends View {
  public FractionalSizeView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public FractionalSizeView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    setMeasuredDimension(width * 70 / 100, 0);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我可以用来在RelativeLayout中对齐其他视图的隐形支柱.


Col*_*ire 11

更新

正如@EmJiHash所指出的,PercentRelativeLayout和PercentFrameLayout在API级别26.0.0中已弃用

考虑使用ConstraintLayout

谷歌推出了名为android.support.percent的新API

1)PercentRelativeLayout

2)PercentFrameLayout

添加编译依赖性就像

compile 'com.android.support:percent:23.1.1'
Run Code Online (Sandbox Code Playgroud)

您可以指定维度百分比,以获得收益RelativeLayout和百分比

 <android.support.percent.PercentRelativeLayout
         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"/>
     <TextView
         app:layout_widthPercent="40%"
         app:layout_heightPercent="40%"
         app:layout_marginTopPercent="15%"
         app:layout_marginLeftPercent="15%"/>
 </android.support.percent.PercentRelativeLayout/>
Run Code Online (Sandbox Code Playgroud)


Eug*_*sov 10

由于PercentRelativeLayout在26.0.0中已弃用,并且RelativeLayout中的LinearLayout之类的嵌套布局会对性能产生负面影响(了解ConstraintLayout的性能优势),因此实现百分比宽度的最佳选择是用ConstraintLayout代替RelativeLayout。

这可以通过两种方式解决。

解决方案#1使用百分比偏移量的准则

布局编辑器

<android.support.constraint.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">

    <TextView
        android:id="@+id/host_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Host"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/host_input" />

    <TextView
        android:id="@+id/port_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Port"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/port_input" />

    <EditText
        android:id="@+id/host_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:inputType="textEmailAddress"
        app:layout_constraintTop_toBottomOf="@+id/host_label"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/guideline" />

    <EditText
        android:id="@+id/port_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:inputType="number"
        app:layout_constraintTop_toBottomOf="@+id/port_label"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.8" />

</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

解决方案2:对EditText使用加权宽度的链

布局编辑器

<android.support.constraint.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">

    <TextView
        android:id="@+id/host_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Host"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/host_input" />

    <TextView
        android:id="@+id/port_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Port"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/port_input" />

    <EditText
        android:id="@+id/host_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:inputType="textEmailAddress"
        app:layout_constraintHorizontal_weight="0.8"
        app:layout_constraintTop_toBottomOf="@+id/host_label"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/port_input" />

    <EditText
        android:id="@+id/port_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:inputType="number"
        app:layout_constraintHorizontal_weight="0.2"
        app:layout_constraintTop_toBottomOf="@+id/port_label"
        app:layout_constraintLeft_toRightOf="@+id/host_input"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

在两种情况下,您都会得到类似的结果

结果视图


Dar*_*ish 7

PercentRelativeLayout已从支持库的修订版26.0.0中弃用.

谷歌推出了名为ConstraintLayout的新布局.

在库模块级build.gradle文件中将库添加为依赖项:

     dependencies {
        compile 'com.android.support.constraint:constraint-layout:1.0.1'
      }
Run Code Online (Sandbox Code Playgroud)

只需添加一个布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

约束

约束可以帮助您保持小部件对齐.您可以使用锚点(如下面显示的约束句柄)来确定各个窗口小部件之间的对齐规则.

  1. Wrap Content:视图根据需要展开以适合其内容.
  2. Match Constraints:在考虑边距后,视图会根据需要进行扩展,以满足其约束的定义.但是,如果给定维度只有一个约束,则视图会展开以适合其内容.在高度或宽度上使用此模式还允许您设置尺寸比率.
  3. Fixed:您可以在下面的文本框中指定特定尺寸,也可以在编辑器中调整视图大小.
  4. Spread:视图均匀分布(在考虑边距后).这是默认值.
  5. Spread inside:第一个和最后一个视图附加在链的每一端的约束上,其余视图均匀分布.
  6. Weighted:当链设置为展开或展开时,您可以通过将一个或多个视图设置为"匹配约束"(0dp)来填充剩余空间.默认情况下,空间均匀分布在设置为"匹配约束"的每个视图之间,但您可以使用layout_constraintHorizo​​ntal_weight和layout_constraintVertical_weight属性为每个视图指定重要性权重.如果您在线性布局中熟悉layout_weight,则其工作方式相同.因此,具有最高权重值的视图获得最大的空间; 具有相同权重的视图获得相同的空间量.
  7. Packed:视图被打包在一起(在计算保证金之后).然后,您可以通过更改链的头部视图偏差来调整整个链的偏差(左/右或上/下).
  8. Center Horizontally or Center Vertically:要快速创建视图链,请选择所有视图,右键单击其中一个视图,然后选择"水平居中"或"垂直居中",以创建水平或垂直链
  9. Baseline alignment:将视图的文本基线与另一个视图的文本基线对齐.
  10. Constrain to a guideline:您可以添加可以约束视图的垂直或水平参考线,并且该参考线将对应用用户不可见.您可以根据相对于布局边缘的dp单位或百分比,将指南定位在布局中.
  11. Adjust the constraint bias:当您向视图的两侧添加约束(并且同一维度的视图大小为"固定"或"换行内容")时,视图将在两个约束之间居中,默认偏差为50%.您可以通过拖动"属性"窗口中的偏移滑块来调整偏差
  12. Set size as a ratio:如果至少有一个视图尺寸设置为"匹配约束"(0dp),则可以将视图大小设置为16:9之比.

您可以从官方文档中了解更多信息.