RelativeLayout中的百分比宽度

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

在这里输入图像描述

我能用下面的XML实现这个布局。 问题是,这有点冒险。 我不得不为主机EditText硬编码一个宽度。 具体来说,我不得不指定:

 android:layout_width="172dp" 

我真的想给主机和端口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> 

您正在寻找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> 

它适用于任何类型的视图,您可以用一些EditText替换按钮,以适应您的需求。

请务必将layout_width设置为0dp否则视图可能无法正确缩放。

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

这并不完全回答原来的问题,这是一个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> 

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

一般来说,最好不要期望股票Android布局太多…

更新1

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

下面引用google的评论:

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


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

那么你可以通过查看指定百分比

像编译依赖关系一样

 compile 'com.android.support:percent:22.2.0 

在那里, 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> 

您不能使用百分比在RelativeLayout中定义视图的维度。 最好的方法是使用LinearLayout和权重,或者自定义布局。

你可以看看新的百分比支持库。

 compile 'com.android.support:percent:22.2.0' 

文档

样品

您可以使用PercentRelativeLayout ,这是设计支持库最近未公开的添加,使得不仅能够指定相对于彼此的元素,还能指定可用空间的总百分比

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"> <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> 

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

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

 dependencies { compile 'com.android.support:percent:22.2.0'//23.1.1 } 

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

 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); } } 

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

更新

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

考虑使用ConstraintLayout

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

1)PercentRelativeLayout

2)PercentFrameLayout

像编译依赖关系一样

 compile 'com.android.support:percent:23.1.1' 

您可以用百分比指定维度,以便同时获得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/> 

PercentRelativeLayout已从支持库的版本26.0.0弃用。

Google推出了名为ConstraintLayout的新布局。

在你的模块级的build.gradle文件中添加这个库作为一个依赖项:

  dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.1' } 

只需添加一个布局文件:

 <?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> 

约束

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

  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等比例。

你可以从官方文档了解更多。

你可以通过布局权重来完成。 一个重量决定了屏幕未被要求的部分如何分割。 给每个EditText一个layout_width为0,以及一些比例权重。 也就是说,如果你想要第一个占用两倍的空间,那么给它一个2的重量,另一个重量为1。

有趣的是,在@olefevre的答案的基础上,不仅可以用“隐形支柱”来做50/50的布局,而且可以用各种各样的涉及两个幂的布局。

例如,这里是一个布局,将宽度分割成四个相等的部分(实际上是三个,权重为1,1,2):

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" > <View android:id="@+id/strut" android:layout_width="1dp" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:background="#000000" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/strut" > <View android:id="@+id/left_strut" android:layout_width="1dp" android:layout_height="match_parent" android:layout_toLeftOf="@+id/strut" android:layout_centerHorizontal="true" android:background="#000000" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignRight="@+id/left_strut" android:text="Far Left" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_toRightOf="@+id/left_strut" android:text="Near Left" /> </RelativeLayout> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignLeft="@id/strut" android:layout_alignParentRight="true" android:text="Right" /> </RelativeLayout> 

只要把你的两个textviews主机和端口放在一个独立的linearlayout水平,并使用android:layout_weight来设置百分比

检查https://github.com/mmin18/FlexLayout ,您可以直接在layout xml中使用百分比或java表达式。

 <EditText app:layout_left="0%" app:layout_right="60%" app:layout_height="wrap_content"/> <EditText app:layout_left="prev.right+10dp" app:layout_right="100%" app:layout_height="wrap_content"/> 

由于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> 

解决方案#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> 

在这两种情况下,你都会得到这样的东西

结果视图