3

アプリの GUI を作成したいと考えています。これは基本的に背景画像であり、その上にいくつかのコントロールがあります。重要な (そしてトリッキーな) 部分は、背景画像の縦横比と縮尺を維持し (完全に適合しない場合は黒い境界線で)、コントロールを背景画像の特定の部分に揃えることです。

AbsoluteLayout (または廃止されたため、そのコピー) を継承し、適切にスケーリング/配置して、背景画像を描画することで、これを解決することを考えていました。次に、スケーリング係数 [測定されたレイアウト サイズ] / [元の背景画像サイズ] を使用して、「スケーリングされた絶対位置」に従って子を配置します。

私の質問は、これを行うためのより良い方法はありますか? 比較的一般的だと私が信じていることを行うには、複雑な方法のように思えますか? (ボタン画像を背景画像ピクセルに完全に配置します)。すべての指針と提案に感謝します。


私は上記の戦略を使用することになりました。完了するために、これが私がしたことです:

クラス ScalingLayout を作成して AbsoluteLayout を拡張し、レイアウトの「仮想寸法」を指定できるようにする 2 つの xml 属性を追加しました。これらは私がビューを配置するディメンションであり、レイアウト全体がスケーリングされたときに、レイアウトはそれらの相対位置が正しくスケーリングされるようにします。したがって、xml では次のようになります。

<ScalingLayout
    mynamespace:virtualWidth="100"
    mynamespace:virtualHeight="100"
    ...
>

カスタム xml 属性を定義し、クラス コンストラクターでそれらの値を取得する方法については、次の質問を確認してください:カスタム属性の定義

さらに、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