アプリの 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 の場合と同様に寸法と位置を指定しますが、仮想寸法の観点から考えてください。