考虑这种布局(从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。
答案 0 :(得分:4)
这很大程度上取决于您要创建的自定义View
和ViewGroup
类的数量。我能想到的具有最少数量的自定义类的实现将是这样的(非常类似于您所描述的):
FrameLayout
,并使用自定义onMeasure()
实施方式将高度与可用宽度相匹配(您已经提到过这个)。LinearLayout
个实例,以使所有网格按钮的大小相同。这种方法的一大缺点是效率。您需要大约36个LinearLayout
个实例才能在更大的9x9网格内创建小型9x9网格......这是纯布局开销的36个视图。
就文本大小而言,我可以想到几种方法来处理这个问题。一种方法是使用Paint.measureTextBounds()
(您可以获取任何Paint
的{{1}}对象进行测量),以确定在每个按钮生成文本后需要的大小测量。不幸的是,这将是一个有点迭代的过程,因为TextView
根据其当前设置测量给定文本,因此您需要:
好消息是你只需要这样做一次,只需将它应用到所有网格按钮,但你需要等到网格按钮被测量。
此处的另一个选项是在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);
}