カスタムviewをxmlで使用する
Android プログラミングで自前で View を継承して作成したカスタムviewをレイアウトファイル(xml)に記述する方法
例えば、時刻を表示するためにTextViewを使っているとして、いちいち
view.setText((new SimpleDateFormat("HH:mm:ss")).format(System.currentTimeMillis()));
などと書くのが面倒だとする。TextView に表示する時刻を持たせて、
view.setTime(System.currentTimeMillis());
としたら、画面には 12:15:07 とか勝手に表示されて欲しいよね。
でも、レイアウトの配置は固定だからレイアウトxmlファイルに自前で作ったクラスを書きたい。
以下手順
1.まずは適当に TextView を拡張したクラスを作成する
public class TimeView extends TextView { private long time; private SimpleDateFormat df; public TimeView(Context context) { this(context, null, 0); } public TimeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TimeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); time = 0; df = new SimpleDateFormat("HH:mm:ss"); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); Date date = new Date(time); setText(df.format(date)); } public void setTime(long time) { if ( time >= 0 ) this.time = time; invalidate(); } public long getTime() { return time; } }
注意点
- TextView の持つ 3種類のコンストラクタを実装する。そうしないと xml ファイルからビューをinflate するところで失敗する
2.作成したクラスをレイアウトファイルに書く
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/YOUR_PACKAGE_NAME" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <YOUR_PACKAGE_NAME.TimeView android:layout_width="160dp" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#c0c080" /> <Button android:id="@+id/nowButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:onClick="setCurrentTime" android:text="@string/now" /> </LinearLayout>
注意点
- xmlns:app 宣言を追加して、自分のアプリケーションのパッケージ名を記載する
- カスタムビューは完全修飾名で記載する
すると
な感じで組込みのViewと同じように使える。
3.あとは使うだけ
public class MainActivity extends Activity { private TimeView timeView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); timeView = (TimeView)findViewById(R.id.currentTimeView); } public void setCurrentTime(View v) { timeView.setTime(System.currentTimeMillis()); } }
View 側でいろいろさせることで、MainActiviy がすっきりしてちょっと嬉しい。
作成したサンプルはここ https://github.com/koko-u/CustomViewSample