カスタムViewでxmlを使用する
前回(d:id:koko_u:20120101)は自分で作成した CustomView クラスをメイン側の xml ファイルに指定するにはどうすれば?という話でしたが、今回はCustomView を作成する時もそのレイアウトは xml ファイルでちょこちょこ作りたいね。という話。
例えばこーんな感じの画面を作成するとして、
中央の3x3タイルは独立して BoardView を作成して、メイン側ではどのタイルが押されたかに応じて
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); resultView = (TextView)findViewById(R.id.resultView); boardView = (BoardView)findViewById(R.id.boardView); boardView.setOnClickListener(new BoardView.OnClickedListener() { @Override public void onClick(WHERE where) { switch (where) { case TL: resultView.setText(getString(R.string.you_clicked, getString(R.string.TL))); break; case TC: resultView.setText(getString(R.string.you_clicked, getString(R.string.TC))); break; // 中略 default: resultView.setText(""); break; } } }); } }
な風にしてみたい。
特に難しいことはなくて、BoardView で使いたいレイアウトを普通に xml ファイルで用意します。
今回トップを TableLayout にしましたが、お好きなもので
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/tlView" android:text="TL" style="@style/cell_view" /> <TextView android:id="@+id/tcView" android:text="TC" style="@style/cell_view"/> <TextView android:id="@+id/trView" android:text="TR" style="@style/cell_view" /> </TableRow> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/clView" android:text="CL" style="@style/cell_view" /> <TextView android:id="@+id/ccView" android:text="CC" style="@style/cell_view"/> <TextView android:id="@+id/crView" android:text="CR" style="@style/cell_view" /> </TableRow> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/blView" android:text="BL" style="@style/cell_view" /> <TextView android:id="@+id/bcView" android:text="BC" style="@style/cell_view"/> <TextView android:id="@+id/brView" android:text="BR" style="@style/cell_view" /> </TableRow> </TableLayout>
同じセルがずらずら並んでいるだけなので、見た目は全部 style として別ファイルにしました
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="cell_view"> <item name="android:layout_height">40dp</item> <item name="android:layout_width">40dp</item> <item name="android:clickable">true</item> <item name="android:gravity">center</item> <item name="android:padding">5dp</item> <item name="android:textSize">24sp</item> <item name="android:background">@drawable/rectangle</item> </style> </resources>
今回の話には関係ないです。/res/values の下に適当な名前で保存。
で、このレイアウト(nine_board.xml)を使用するカスタムビューを BoardView として作成
public class BoardView extends TableLayout { public enum WHERE { TL, TC, TR, CL, CC, CR, BL, BC, BR }; private LayoutInflater inf; private OnClickedListener listener; private TextView TLView, TCView, TRView, CLView, CCView, CRView, BLView, BCView, BRView; public BoardView(Context context) { this(context, null); } public BoardView(Context context, AttributeSet attrs) { super(context, attrs); inf = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inf.inflate(R.layout.nine_board, this); TLView = (TextView)layout.findViewById(R.id.tlView); TLView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onClick(WHERE.TL); } }); TCView = (TextView)layout.findViewById(R.id.tcView); TCView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onClick(WHERE.TC); } }); // おなじなので省略 } public void setOnClickListener(OnClickedListener l) { this.listener = l; } interface OnClickedListener { public void onClick(WHERE where); } }
ポイントは、作成した nine_board.xml のトップを TableLayout で作成したので、カスタムビューも TableLayout を継承して作成する。
LayoutInflater#inflate を呼び出す時の第2引数として this 自分自身を指定する。
くらいですかね。OnClickListener はまあ適当。作ったカスタムビューをメインのレイアウトで
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schamas.android.com/apk/res/com.sample.kokou" android:id="@+id/RelativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:id="@+id/resultView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_margin="10dp" android:textSize="20sp" > </EditText> <com.sample.kokou.BoardView android:id="@+id/boardView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/resultView" android:layout_centerHorizontal="true" > </com.sample.kokou.BoardView> </RelativeLayout>
な感じで指定すれば、普通に独立したビューとして利用できます。