3

我想为我的应用程序创建一个 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 一样,但要考虑虚拟尺寸。

4

0 回答 0