AndroidのボタンデザインをXMLで変更する
初期状態でのAndroidのボタンは味気ないので、ボタンのデザインを変更してみましょう。
ボタンのデザインに画像を使用することもできますが、XMLでシェイプを指定して気軽にデザイン変更をすることができます。まずは、ボタンのデザインを用意します。 ボタンには、ボタンの押下の有無、フォーカスの有無により合計4つの状態がありますので、それぞれの状態に対してシェイプを指定します。
数値のボタン用に黒いデザインを作ってみましょう。ソースは次のようになります。
<!-- ボタンが押されている -->
<!-- フォーカスされていない -->
<item android:state_pressed="true"
android:state_focused="false">
<layer-list>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/push_start"
android:centerColor="@color/push_center"
android:endColor="@color/push_end"
android:centerY="0.2"
android:angle="-90"/>
<padding
android:left="1dip"
android:top="dip"
android:right="1dip"
android:bottom="1dip" />
<corners android:radius="15dip" />
<stroke android:width="1dip"
android:color="#999999"
/>
</shape>
</item>
</layer-list>
</item>
<!-- ボタンが押されていない -->
<!-- フォーカスされていない -->
<item android:state_pressed="false"
android:state_focused="false">
<layer-list>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/black_start"
android:centerColor="@color/black_center"
android:endColor="@color/black_end"
android:centerY="0.2"
android:angle="-90"/>
<padding
android:left="1dip"
android:top="1dip"
android:right="1dip"
android:bottom="1dip" />
<corners android:radius="15dip" />
<stroke android:width="1dip"
android:color="@color/black_center"
/>
</shape>
</item>
</layer-list>
</item>
<!-- ボタンが押されている -->
<!-- フォーカスされた -->
<item android:state_pressed="true"
android:state_focused="true">
<layer-list>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/push_start"
android:centerColor="@color/push_center"
android:endColor="@color/push_end"
android:centerY="0.2"
android:angle="-90"/>
<padding
android:left="1dip"
android:top="1dip"
android:right="1dip"
android:bottom="1dip" />
<corners android:radius="15dip" />
<stroke android:width="1dip"
android:color="#FF6600"
/>
</shape>
</item>
</layer-list>
</item>
<!-- ボタンが押されていない -->
<!-- フォーカスされた -->
<item android:state_pressed="false"
android:state_focused="true">
<layer-list>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/black_start"
android:centerColor="@color/black_center"
android:endColor="@color/black_end"
android:centerY="0.2"
android:angle="-90"/>
<padding
android:left="1dip"
android:top="1dip"
android:right="1dip"
android:bottom="1dip" />
<corners android:radius="15dip" />
<stroke android:width="1dip"
android:color="#FF6600"
/>
</shape>
</item>
</layer-list>
</item>
</selector>
このファイルを「/res/drawable-nodip」に配置します。 他にも演算操作のボタン用にグレーのデザイン、クリア、オールクリアのボタン用に赤のデザインを用意します。
android:startColor="@color/black_start"で色を定義しています。実際の色の指定は「/res/values/color.xml」の中で設定します。メニューより[ファイル]-[新規]-[Android XML File]を開き、color.xmlを作成してください。
- Project: MyCalc
- File: color.xml
- リソースタイプ: Values
color.xmlに色の定義を追加します。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="red_start">#ff4040</color>
<color name="red_center">#541515</color>
<color name="red_end">#a82a2a</color>
<color name="gray_start">#e0e0e0</color>
<color name="gray_center">#666666</color>
<color name="gray_end">#999999</color>
<color name="black_start">#eeeeee</color>
<color name="black_center">#3e3e3e</color>
<color name="black_end">#555555</color>
<color name="push_start">#8bff00</color>
<color name="push_center">#5da800</color>
<color name="push_end">#2e5400</color>
</resources>
作成したデザインをボタンに反映します。main.xmを開き、各ボタンにandroid:backgroundを追加してデザインbutton_blackを指定します。また、フォントサイズandroid:textSizeと、文字色android:textColorも指定します。
・・・省略・・・ <Button android:background="@drawable/button_black" android:textSize="50sp" android:textColor="#FFFFFF" ・・・省略・・・
実行してボタンのデザインが変わったことを確認してみましょう。
どうですか? AndroidではXMLによるシェイプの設定によりこんなに簡単にデザインを変更できるんです。android:background=には画像も指定できるので、さらにグラフィカルな表現にすることもできます。
今回使用したプロジェクトファイルは、記事冒頭からダウンロードできます。
更なる機能拡張
一般の電卓にはメモリー機能のボタンや%のボタンがあります。これらを追加するには状態遷移の追加が必要になりますが、Stateインターフェースの導入により容易にコーディングできるでしょう。また、%ボタンの処理を追加するには新しい「状態依存の処理」を追加することになるでしょう。この場合、Stateインターフェースにメソッドを追加することになります。それによりStateインターフェースを実装しているクラスすべてに修正が必要です。修正クラスが多くなり大変ですが、うっかりメソッドの追加を忘れてもコンパイルエラーとなり知らせてくれるので、実装漏れの心配がなくなります。
もしStateパターンを使っていなかったとしたら、どうでしょうか。従来ながらの手法、フラグとif文でコーディングする方法であれば、処理の実装漏れをしてもバグが発生するまで気づかないことでしょう。Stateパターンは安全に機能拡張を行える優れた手法であると言えます。
まとめ
- 電卓のベース処理ロジックにはGoFのデザインパターン「Stateパターン」を適用します。
- 状態遷移を表現するには「Stateパターン」が有効です。
- 「Stateパターン」により、機能追加により状態が増えた場合にも修正が少なくて済みます。
- Androidアプリ開発では画面デザインをXMLで作成することができます。プログラムの完成後にデザインを変更する場合も、プログラム本体に修正を加えることなく、XMLの修正だけでデザインを変更できます。
- ユーザのフィードバックが不要なちょっとしたメッセージはToast通知を使用します。
参考文献
- 『増補改訂版Java言語で学ぶデザインパターン入門』 結城浩 著、ソフトバンククリエイティブ、2004年6月
- CodeZine 『StateパターンでCSVを読む』 επιστημη 著、2010年12月
- japan.internet.com 『デザインパターンの使い方: State』 Jeff Langr 著、2008年12月

