Android:如何使用屏幕尺寸缩放布局

时间:2012-12-29 03:31:50

标签: android android-layout android-xml

考虑这种布局(从here拉出来):

enter image description here

我想了解使用屏幕尺寸进行此布局缩放的原理。对于广场,自定义onMeasure功能可以很好地工作:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}

下面的自定义Togglebuttons和Imagebuttons的宽度和高度应缩放以填充屏幕的其余部分,减去layout_margins,并且内部的文本和图像应缩放以填充按钮,减去填充。外边距也应该缩放。

我的第一个想法是使用相对布局来定位按钮,并使用layout_margin / padding属性来创建边距。但是,相对布局和layout_margin / padding需要固定的像素值,因此它们不可伸缩。

然后我考虑使用带有layout_weights的嵌套线性布局来定位按钮,并使用占位符视图来创建边距。虽然这些技术是可扩展的,但它们不适用于按钮,因为按钮具有许多需要固定像素值的属性(文本大小,图像大小,角半径等)。例如,此限制意味着以下xml:

<ToggleButton 
    android:layout_weight="1"
    style="@style/myButton"
    [...] />
<View 
    android:layout_weight="1"/>
<ImageButton 
    android:layout_weight="1"
    style="@style/myButton"
    [...] />

不一定会使两个按钮和它们之间的空间宽度相同。这一切都取决于按钮的文字大小,图像大小等。

我已经看了this question,但我觉得对于这样一个简单的问题应该有一个更简单的解决方案,不应该求助于过多的非XML。

3 个答案:

答案 0 :(得分:4)

这很大程度上取决于您要创建的自定义ViewViewGroup类的数量。我能想到的具有最少数量的自定义类的实现将是这样的(非常类似于您所描述的):

  • 为最大的广场定制FrameLayout,并使用自定义onMeasure()实施方式将高度与可用宽度相匹配(您已经提到过这个)。
  • 使用权重嵌套LinearLayout个实例,以使所有网格按钮的大小相同。

这种方法的一大缺点是效率。您需要大约36个LinearLayout个实例才能在更大的9x9网格内创建小型9x9网格......这是纯布局开销的36个视图。


就文本大小而言,我可以想到几种方法来处理这个问题。一种方法是使用Paint.measureTextBounds()(您可以获取任何Paint的{​​{1}}对象进行测量),以确定在每个按钮生成文本后需要的大小测量。不幸的是,这将是一个有点迭代的过程,因为TextView根据其当前设置测量给定文本,因此您需要:

  1. 设置文字大小
  2. 测量边界
  3. 检查身高
  4. 重复直到尺寸合适
  5. 好消息是你只需要这样做一次,只需将它应用到所有网格按钮,但你需要等到网格按钮被测量。

    此处的另一个选项是在Paint之类的内容中显示图像而不是文本,这可以将内容缩放到其大小。您可以使用我编写的TextDrawable之类的内容将文本内容设置为可扩展且无质量损失的图像。


    现在回到布局。你可以通过创建一个自定义ImageView来测量和布置网格(名称ViewGroup已经被采取了......而且它不能完全用于此目的,因此可以获得大量的效率,所以让我们称之为GridLayout)。创建自定义BlockLayout将允许您测量每个块的大小,并在网格中使用单个父级而不是4个BlockLayout实例布置9个子视图。这与您测量整体方块的方式基本相同,只是均匀分配。

    然后,您可以使用10个布局开销实例构建整个布局......如果您可以将整个内容编码为单个LinearLayout,则可以更少。

    基本上,您可以编写的用于展平视图层次结构的代码越多,整个应用程序的运行效果就越好。

    HTH

答案 1 :(得分:4)

如果使用“dp”构建视图,基本上,它与eack屏幕大小的大小相同。
在大多数情况下,您希望视图会根据屏幕大小调整自身大小。
当然,在大多数情况下,您需要为平板电脑构建单独的布局。
但是,除了我可以建议你做下一步:

1.将this库添加到项目中。

2.现在在您的布局中,您可以编写如下视图:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="I'm scalable!" 
    android:textSize="@dimen/_12sdp"/>

在此示例中,TextView将在每个屏幕尺寸上缩放。

3.预览所有屏幕尺寸以查看结果。

答案 2 :(得分:0)

为了补充Devnuwired的答案,您可以编写与此类似的方法将TextDrawable文本添加到ImageButton

private void addText(String text, ImageButton button, int colour) {
    TextDrawable d = new TextDrawable(this);
    d.setText(text);
    d.setTextColor(colour);
    d.setTextAlign(Layout.Alignment.ALIGN_CENTER);
    button.setImageDrawable(d);
}

或者

private void addText(String text, int buttonID, int colour) {
    TextDrawable d = new TextDrawable(this);
    d.setText(text);
    d.setTextColor(colour);
    d.setTextAlign(Layout.Alignment.ALIGN_CENTER);
    ((ImageButton) findViewById(buttonID)).setImageDrawable(d);
}