我想为我的应用创建一个GUI,它实际上是一个背景图像,上面有一些控件。重要的(也是棘手的)部分是背景图像应该保持其纵横比和比例(如果它不是完美的合适,则使用黑色边框),并且控件与背景图像的某些部分对齐。
我正在考虑通过继承AbsoluteLayout(或者我的副本,因为它已被弃用)来解决这个问题,正确缩放/定位并让它绘制我的背景图像。然后,我会根据“缩放的绝对位置”,使用缩放系数[测量的布局大小] / [原始背景图像大小]将其子项放置。
我的问题是,有更好的方法吗?做一些我认为比较常见的事情似乎是一种复杂的方式? (完美地对齐背景图像像素上的按钮图像)。我很感谢所有的指示和建议。
我最终使用了上述策略。完成后,我就是这样做的:
我创建了一个ScalingLayout类,扩展了AbsoluteLayout,并添加了两个xml属性,允许我为布局指定“虚拟维度”。这些是我定位视图的尺寸,并且布局确保在缩放整个布局时正确缩放这些相对位置。所以在xml中它看起来像:
<ScalingLayout
mynamespace:virtualWidth="100"
mynamespace:virtualHeight="100"
...
>
有关如何定义自定义xml属性并在类构造函数中获取这些值的信息,请查看以下问题:Defining custom attrs
此外,我在ScalingLayout中覆盖了onMeasure和onLayout。
// Overridden to retain aspect of this layout view
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
double aspect = getSize(widthMeasureSpec) / (double)getSize(heightMeasureSpec);
// Those are from XML layout
double virtualAspect = _virtualWidth / (double)_virtualHeight;
int width, height;
measureChildren(widthMeasureSpec, heightMeasureSpec);
if(aspect > virtualAspect) {
height = getSize(heightMeasureSpec);
width = height * virtualAspect;
} else {
width = getSize(widthMeasureSpec);
height = width / virtualAspect;
}
setMeasuredDimension(width, height);
}
...
protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
double factor = (right - left) / (double)_virtualWidth;
nchildren = getChildCount();
for(int i = 0; i < nchildren; i++) {
View child = getChildAt(i);
LayoutParams lp = child.getLayoutParams();
// Scale child according to given space
child.layout(lp.x * factor,
lp.y * factor,
(lp.x + child.getMeasuredWidth()) * factor,
(lp.y + child.getMeasuredHeight()) * factor );
}
}
现在,只需在XML中添加视图并指定尺寸和位置,就像AbsoluteLayout一样,但请考虑虚拟尺寸。