我正在为Android应用中的登录Activity
制作表单布局。下面的图片是我希望它的样子:
我能够使用以下 XML 实现此布局。问题是,它有点hackish。我不得不为主机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>
答案 0 :(得分:730)
您正在寻找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>
它适用于任何类型的View,您可以使用一些EditText替换按钮以满足您的需求。
请务必将layout_width
设置为0dp
,否则您的观看次数可能无法正常缩放。
请注意,权重总和不必等于1,我发现这样更容易阅读。您可以将第一个权重设置为7,将第二个权重设置为3,它将得到相同的结果。
答案 1 :(得分:283)
这并没有完全回答最初的问题,即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布局中存在太多期待......
答案 2 :(得分:131)
正如@EmJiHash指出 PercentRelativeLayout 在 API级别26.0.0
中已弃用以下引用谷歌评论:
此类在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>
答案 3 :(得分:78)
您无法使用百分比在RelativeLayout中定义视图的尺寸。最好的方法是使用LinearLayout和权重,或自定义布局。
答案 4 :(得分:31)
答案 5 :(得分: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);
}
}
这是我可以用来在RelativeLayout中对齐其他视图的隐形支柱。
答案 6 :(得分:11)
<强>更新强>
正如@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/>
答案 7 :(得分:6)
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>
<强>约束强>
约束可以帮助您保持小部件对齐。您可以使用锚点(如下面显示的约束句柄)来确定各个小部件之间的对齐规则。
Wrap Content
:视图会根据需要展开以适合其内容。Match Constraints
:在考虑边距后,视图会根据需要进行扩展,以满足其约束的定义。但是,如果给定维度只有一个约束,则视图会展开以适合其内容。在高度或宽度上使用此模式还允许您设置尺寸比率。Fixed
:您可以在下面的文本框中指定特定尺寸,也可以在编辑器中调整视图大小。Spread
:视图均匀分布(在考虑边距后)。这是默认设置。Spread inside
:第一个和最后一个视图附加在链的每一端的约束上,其余视图均匀分布。Weighted
:当链设置为展开或展开时,您可以通过将一个或多个视图设置为“匹配约束”(0dp)来填充剩余空间。默认情况下,空间均匀分布在设置为“匹配约束”的每个视图之间,但您可以使用layout_constraintHorizontal_weight和layout_constraintVertical_weight属性为每个视图指定重要性权重。如果您在线性布局中熟悉layout_weight,则其工作方式相同。因此,具有最高权重值的视图获得最大的空间;具有相同权重的视图获得相同的空间量。Packed
:视图被打包在一起(在考虑边距之后)。然后,您可以通过更改链条的头部视图偏差来调整整个链条的偏差(左/右或上/下)。Center Horizontally or Center Vertically
:要快速创建一系列视图,请选中所有视图,右键单击其中一个视图,然后选择“水平居中”或“垂直居中”,以创建水平或垂直链Baseline alignment
:将视图的文本基线与另一个视图的文本基线对齐。Constrain to a guideline
:您可以添加可以约束视图的垂直或水平指南,并且指南对应用用户不可见。您可以根据相对于布局边缘的dp单位或百分比,在布局中定位指南。Adjust the constraint bias
:当您向视图的两侧添加约束(并且同一维度的视图大小为“固定”或“换行内容”)时,视图将在两个约束之间居中默认偏差为50%。您可以通过拖动“属性”窗口中的偏置滑块Set size as a ratio
:如果至少有一个视图尺寸设置为“匹配约束”(0dp),则可以将视图大小设置为16:9之比。 您可以从官方doc了解更多信息。
答案 8 :(得分:6)
由于PercentRelativeLayout在26.0.0中已弃用,而且RelativeLayout中的LinearLayout等嵌套布局对性能(Understanding the performance benefits of 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>
在这两种情况下,你都会得到类似的东西
答案 9 :(得分:3)
您可以通过布局权重来完成此操作。重量决定了如何分割屏幕的无人认领部分。给每个EditText一个layout_width为0,以及一些比例权重。即,如果你想让第一个占据两倍的空间,那么给一个重量为2,另一个重量为1。
答案 10 :(得分:3)
有趣的是,在@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>
答案 11 :(得分:1)
检查https://github.com/mmin18/FlexLayout,您可以直接在布局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"/>