我正在为我的Android应用程序中的登录活动做一个表单布局。下图是我想让它看起来的样子:

我能够使用以下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>

当前回答

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

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

其他回答

你可以通过布局权重来实现。权重决定了屏幕上无人认领的部分如何划分。给每个EditText一个0的layout_width和一些成比例的权重。也就是说,如果你想让第一个占用两倍的空间,给一个权重为2,给另一个权重为1。

只是把你的两个textviews主机和端口在一个独立的线性布局水平和使用android:layout_weight使百分比

这并没有完全回答最初的问题,即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布局抱有太多期望……

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

在这两种情况下,你会得到这样的结果

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