AbsoluteLayoutで足が生える
今までずっと悩んでいたwidgetの動的な配置。
結論から言うとこれはAbsoluteLayoutを使うと解決できる。
その手順を簡単に説明すると次のようになる。
- AbsoluteLayoutをnewする。
- 配置したいwidgetをnewする。
- 配置したいwidgetにAbsoluteLayout.LayoutParamsをセットする。
- AbsoluteLayoutのaddViewメソッドで配置したいwidgetを追加する。
ここで一番やっかいなのはLayoutParamsである。
AndroidのドキュメントのClass Indexで"LayoutParams"を検索するとわかるが、
なんとLayoutParamsは複数存在するのだ。例えば"Gallery.LayoutParams"や"ViewGroup.LayoutParams"とか。
初めViewGroup.LayoutParamsを使っていて、どうしてもaddViewでエラーがでると悩んだ。
さらに各LayoutParamsによって引数が異なる。ViewGroup.LayoutParamsの引数は幅と高さだが、
AbsoluteLayout.LayoutParamsは幅、高さ、位置x、位置yの4つを引数にとる。なんだかなあ。
配置したwidgetを移動するには今回はlayoutメソッドを使っている。
final void layout(int wl, int wt, int l, int t, int r, int b)
wlとwtは値を変えても挙動に変化がなかったので今回は気にしない。
l、t、r、bはそれぞれwidgetの左の位置、上の位置、右の位置、下の位置である。
もしかしたら移動には違う方法があるのかもしれない。
それにしてもこのLayoutParamsがいっぱいあるのはどうにかならないんだろうか。
ややこしい上にいちいちxxx.LayoutParamsとしないといけないので記述が長くなる。
そんな感じでソース。ボタンを押すとボタンが動きます。それだけ。
足の生えたボタンということで。疲れた疲れたー。
以下動作画面。やっぱり画像だと動きがないから微妙だなあ。
http://gyazo.com/96c699923e6e5e5a3c049dc7781c302d.png
http://gyazo.com/9e320ff05f21d258f65c7f291e14bd6e.png
http://gyazo.com/38dcc4194836d1a5801409c7bdcf3ccf.png
package net.swelt.android.widgetbuttontest; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.AbsoluteLayout; import android.widget.AbsoluteLayout.LayoutParams; import java.util.Random; public class WidgetButtonTest extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); AbsoluteLayout al = new AbsoluteLayout(this); setContentView(al); Button bt = new Button(this); bt.setLayoutParams(new LayoutParams(100, LayoutParams.WRAP_CONTENT, 110, 75)); bt.setText("Button1"); al.addView(bt); bt.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Button bt = (Button) v; Random rand = new Random(); int x = rand.nextInt(320 - bt.getWidth()); int y = rand.nextInt(200 - bt.getHeight()); bt.layout(0, 0, x, y, x+bt.getWidth(), y+bt.getHeight()); } }); } }