6月 28
まずはお詫びから、6/5のエントリで「カスタムダイアログと遷移アニメーション」のソースコードが GoogleCode のレポジトリに登録されていませんでした。なぜかローカルの svn のレポジトリに登録されていました。orz 本日、登録しましたのでよろしくー。

で、今日のお題は「レイアウトを分割しよう!」です。簡単な場合やひとりで開発する場合はさておき複雑な画面(Activity)やひとつの画面を複数人で開発しなければならない場合、レイアウトファイルが大きくなりすぎて見通しが悪くなったり他の人の修正とコンフリクトを起こしひどいめにあったりする場合がよくあると思います。今回はそんなときに使える Tips です。

今日のサンプルアプリ

device-1.png

今日のサンプルアプリの画面はこんな感じです。リセットボタンが1つに数字が3つ。数字はそれぞれ別個のTextViewです。青のビューの数字が1の位、緑のビューの数字が十の位、赤のビューの数字が百の位を表しています。アプリを起動するとカウントアップが開始され999を超えると000に戻ります。またリセットボタンを押すことで000に戻すこともできます。普通に作ればなんということのないアプリです。今回はこれをカスタムビューと複数のレイアウトを使って作りました。

blog-1.png

aaa.xml, bbb.xml, ccc.xml に対応するカスタムビューを Aaa, Bbb, Ccc をそれぞれ用意します。カスタムビューは FrameLayout または LineraLayout のサブクラスにするといいでしょう。ここで示す例では FrameLayout のサブクラスとしています。xml ファイルから読み込まれるコンストラクタで対応するレイアウトファイルを inflate し、それを addView します。

public class Aaa extends FrameLayout {

    public Aaa(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutParams params =
            new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        View child = inflate(context, R.layout.aaa, null);
        addView(child, params);

aaa.xml
bbb.xml
ccc.xml

Aaa
Bbb
Ccc

こうすることでレイアウトファイル Aaa.xml 上のウィジェットの制御は全てカスタムビュー Aaa に集約させることができます。

でもレイアウトファイルをまたぐような連携はどうするの?もちろんレイアウトを分割したとはいえ同じ Activity 上のウィジェットです。普通に findViewById を利用すれば相互にアクセス可能です。でもこれじゃーおもしろくありませんし、なによりモジュールはできるだけ疎に保つべきという定石に反します。こういうときはカスタムモジュールに外部から操作できるメソッドと通知を受け取るリスナーを用意してあげましょう。

DigitListener

blog-2.png

リスナーで受け取ったコールバックの中で UI を操作するとスレッドの例外が発生するので必ず Handler を用いて UI スレッドに処理を post してあげるのを忘れずに。

サンプルコード

サンプルアプリのソースコードは Google Code で公開しています。完全なサンプルコードを参照したい場合はそちらをどうぞ。



Posted by sak+

One Response to “レイアウトを分割しよう!”

  1. […] 編) Technology Add comments 以前、『レイアウトを分割しよう!』という記事を書きましたがそれと同じことが fragment […]

preload preload preload