2012年6月6日水曜日

AndroidでSilverlightのWrapPanel風のViewGroupが欲しい

AndroidでSilverlightのWrapPanelのように自動で折り返すViewGroupが欲しいです。
デフォルトじゃないみたいなので、いろいろ漁ってると以下の記事を発見。

Androidでボタンを横に並べて自動で折り返す

ほほー。RelativeLayoutでござるか。

使 っ た こ と な い ん で す よ ね 。

上記の記事を使いまわしが効くようにコントロール化してみました。
かなり適当。
public class WrapLayout extends RelativeLayout {

    public WrapLayout(Context context) {
        super(context);
    }

    public WrapLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WrapLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void addView(View child) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child);
    }

    @Override
    public void addView(View child, int width, int height) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, width, height);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, params);
    }

    @Override
    public void addView(View child, int index) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, index);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, index, params);
      }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {

        super.onWindowFocusChanged(hasWindowFocus);

        // 子供の数を取得
        int l = this.getChildCount();
        // 無いなら何もしない
        if (l == 0) {
          return;
        }

        // ディスプレイの横幅を取得
        WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();

        // 1行最大長
        int max = display.getWidth();

        // 一番最初は基点となるので何もしない
        View pline = this.getChildAt(0);
        // 現在の1行の長さ
        int currentTotal = pline.getWidth();
        for (int i = 1; i < l; i++) {
            int w = this.getChildAt(i).getWidth();
            RelativeLayout.LayoutParams layoutParams =
                    (RelativeLayout.LayoutParams) this.getChildAt(i).getLayoutParams();

            // 横幅を超えないなら前のボタンの右に出す
            if (max > currentTotal + w) {
                // 現在長に処理対象コントロール長を加算
                currentTotal += w;
                layoutParams.addRule(RelativeLayout.ALIGN_TOP, this.getChildAt(i - 1).getId());
                layoutParams.addRule(RelativeLayout.RIGHT_OF, this.getChildAt(i - 1).getId());
            } else {
                // 横最大長を超過した場合は折り返す
                layoutParams.addRule(RelativeLayout.BELOW, pline.getId());

                // 基点を変更
                pline = this.getChildAt(i);

                // 長さをリセット
                currentTotal = pline.getWidth();
            }
        }
    }
}


わかってます。onWindowFocusChangedにaddViewしたらダメじゃね?ってのはわかってます。
とりあえずです。
[[Activity]]
public class MainActivity extends Activity {
    /** Called when the activity is first created. */

    String[] strings = { "てst1", "てst2", "てst3", "てst4", "てst5", "てst6", "てst7", "てst8", "てst9", "てst10", "てst111111a", "てst111", "てst234"};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WrapLayout layout = (WrapLayout)this.findViewById(R.id.FixedGridLayout);
        for (String string : strings) {
            Button btn = new Button(this);
            btn.setText(string);
            //btn.setId(random.nextInt(Integer.MAX_VALUE));
            layout.addView(btn);
        }
    }
}
[[出力結果]]

良い感じ。

0 件のコメント:

コメントを投稿