4

考虑这个布局(从这里拉):

在此处输入图像描述

我想了解使这种布局随屏幕尺寸缩放的原理。对于正方形,自定义 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"
    [...] />

不一定会使两个按钮以及它们之间的空间都具有相同的宽度。这完全取决于按钮的文本大小、图像大小等。

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

4

3 回答 3

6

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

1.将此库添加到您的项目中。

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

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

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

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

于 2013-11-12T09:41:52.433 回答
4

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

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

这种方法的最大缺点是效率。您将需要大约 36 个LinearLayout实例来在较大的 9x9 网格内创建小的 9x9 网格……这是纯布局开销的 36 个视图。


至于文本大小,我可以想到几种方法来处理这个问题。一种是使用Paint.measureTextBounds()(您可以获取Paint任何对象进行TextView测量)来确定在测量后每个按钮中的文本需要多大的尺寸。不幸的是,这将是一个迭代过程,因为Paint根据当前设置测量给定文本,因此您需要:

  1. 设置文字大小
  2. 测量范围
  3. 检查高度
  4. 重复直到尺寸刚好合适

好消息是您只需执行一次并将其应用于所有网格按钮,但您需要等到网格按钮被测量。

这里的另一种选择是在类似的内容中显示图像而不是文本ImageView,这可以为您缩放内容到它的大小。您可以使用我编写的TextDrawable之类的东西将文本内容设置为可缩放而不会损失质量的图像。


现在回到布局。ViewGroup您可以通过创建一个自定义来测量和布置网格来获得大量的效率(这个名称GridLayout已经被使用......它并不能完全满足这个目的,所以我们称之为BlockLayout)。创建自定义BlockLayout将允许您测量每个块的大小,并在一个网格中布置 9 个子视图,使用单个父项而不是 4 个LinearLayout实例。这基本上和你测量整个正方形的方法一样,只是平分。

然后,您可以仅使用 10 个布局开销实例来构建整个布局……如果您可以将整个事物编码为单个ViewGroup.

基本上,您可以编写越多的代码来扁平化视图层次结构,您的应用程序将整体运行得越好。

高温高压

于 2012-12-29T04:54:58.857 回答
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);
}
于 2013-01-01T17:06:48.010 回答