将UI元素的位置/大小设置为屏幕大小的百分比

78

我正在尝试确定在创建布局时是否可以使用百分比位置/大小。我想要的是像这样的东西...

^
|
|
| 68%
|
|
v
Gallery (height equivalent of 16% total screen size)
^
| 16%
v

我正在测试一台设备,它在横向方向上拥有800x480个实际像素的显示屏,并且我目前正在使用以下方式进行强制...

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" > 
    <Gallery 
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="80px"
        android:layout_marginTop ="320px"
    />
</RelativeLayout>

显然我不想硬编码固定的px单位,但是我不能在layout_marginTop(例如)中使用68%0.68。 我查看了dp单位,但我不确定是否可以用这种方式解决。

我必须承认UI设计是我的弱点,因此非常感谢任何建议。

编辑:对于将来寻找类似答案的人,请遵循Alan Moore的建议,我有以下解决方案完全符合我的要求...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="@drawable/bground"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.68"
        android:background="@android:color/transparent"
    />
    <Gallery 
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.16"
    />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.16" 
        android:background="@android:color/transparent"
    />
</LinearLayout>

我找到了一些使用layout_weight的其他示例,并决定将TextView的高度设置为0dp,并使用浮点数来设置权重。工作得很好。 :)

5个回答

74
我认为您想要设置 android:layout_weight,类似于以下方式(我只是将文本视图放置在上方和下方作为占位符):

http://developer.android.com/resources/tutorials/views/hello-linearlayout.html

  <LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="68"/>
    <Gallery 
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="0dp"

        android:layout_weight="16"
    />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="16"/>

  </LinearLayout>

我会尝试这个 - 不过我需要将TextView元素设置为透明,因为它将有一个背景图像(抱歉忘了提到这一点)。不过应该是可行的,谢谢。 - Squonk
@AlanMoore 这对我也有效,但如果我想将高度和宽度都定义为宽度,我该怎么做? - Thev
嗨@TheveshTheva--如果我理解正确的话,您想将其设置为水平方向,然后将layout_width更改为类似于“wrap_content”。 - Alan Moore
2
很好的答案,但请注意,如果您将LinearLayout的android:layout_weight="1"替换为android:weightSum="100"并将所有子项的高度设置为0dp,则可以删除一个TextView。这是因为在这种情况下,在LinearLayout上设置android:layout_weight是无关紧要的。如果您设置LinearLayout的android:weightSum,则所有未使用的权重都将保持为空(正如预期的那样)。 - Jacob R
@JacobR,说得非常好!我实际上从未使用过weightSum,但一定会记在心里。 - Alan Moore
显示剩余2条评论

19

使用百分比相对布局(PercentRelativeLayout)百分比帧布局(PercentFrameLayout),这两个布局可以从百分比支持库(Percent Support Library)中获取。

<android.support.percent.PercentFrameLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
     <TextView
          android:layout_width="match_parent"
          app:layout_heightPercent="68%"/>
     <Gallery 
          android:id="@+id/gallery"
          android:layout_width="match_parent"
          app:layout_heightPercent="16%"/>
     <TextView
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_width="match_parent"/>
</android.support.percent.PercentFrameLayout>

2
天啊,太棒了。他们为什么要花这么长时间才添加这个功能呢?谢谢!你刚刚让我的一天变得美好了。 :) - Kenny Wyland
2
有点混乱,你需要自定义布局才能做到这一点,而实际上它应该在内置布局中提供... - Richard Lalancette
如何在尺寸文件中添加68%和16%。 - Tushar Pandey
7
这两种布局方式在Android API级别26.1.0之后已被废弃。 - Dan

18

对于 TextView 及其子类(例如 Button),您可以从 WindowManager 获取显示大小,然后将 TextView 的高度设置为其中的某个分数:

Button btn = new Button (this);
android.view.Display display = ((android.view.WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
btn.setHeight((int)(display.getHeight()*0.68));

9
上述问题也可以通过使用Guidelines在ConstraintLayout中解决。

下面是代码片段。
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.constraint.Guideline
    android:id="@+id/upperGuideLine"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.68" />

<Gallery
    android:id="@+id/gallery"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@+id/lowerGuideLine"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/upperGuideLine" />

<android.support.constraint.Guideline
    android:id="@+id/lowerGuideLine"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.84" />

</android.support.constraint.ConstraintLayout>

1

谢谢,我想知道我是否必须在代码中进行操作而不是在布局XML中。 - Squonk
1
可以使用权重在XML中完成此操作,无需额外的要求或处理。 - RichieHH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接