iPhoneのロック解除画面のようなボタンをAndroidで作成する

iPhoneのロック解除画面のようなボタンの作成を、Androidで試みました。

画像を用意する

Androidのデフォルトテーマのボタンは上下左右に隙間があるので、隙間が無いボタンの画像を用意しました。なお、これらの画像はpixelmatorの体験版で自作しました。

通常時

汎用性を持たせるため、全体を透過にしました。

押された時

こちらは透過にはなっていません。デフォルトにあわせてオレンジにしました。

StateListで状態を定義

作成した画像を、下記のようにボタンの状態に割り当てました。

res/drawable/btn_custom.xml
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:state_pressed="true" android:drawable="@drawable/btn_custom_normal_pressed" />
	<item android:state_enabled="true" android:state_window_focused="true"
		android:drawable="@drawable/btn_custom_normal" />
</selector>

ボタンのスタイル定義

属性をまとめて指定できるよう、スタイルを"btn_custom"として定義しました。フォントが立体的に見えるように、shadow関連をちょっといじりました。

res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
	<style name="btn_custom">
		<item name="android:background">@drawable/btn_custom</item>
		<item name="android:textColor">#FFF</item>
		<item name="android:textSize">20dp</item>
		<item name="android:shadowColor">#000</item>	
		<item name="android:shadowDx">-1.0</item>	
		<item name="android:shadowDy">-1.0</item>	
		<item name="android:shadowRadius">1.0</item>	
	</style>
</resources>

レイアウトの定義

LinearLayoutで9x9のボタンを並べ、それぞれにスタイルを適用しました。

res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent" android:background="#555"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="@string/hello" />
	<LinearLayout android:layout_height="wrap_content"
		android:id="@+id/linearLayout1" android:layout_width="match_parent">
		<Button android:text="1" android:id="@+id/button1" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="2" android:id="@+id/button2" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="3" android:id="@+id/button3" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
	</LinearLayout>
	<LinearLayout android:layout_height="wrap_content"
		android:id="@+id/linearLayout2" android:layout_width="match_parent">
		<Button android:text="4" android:id="@+id/button4" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="5" android:id="@+id/button5" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="6" android:id="@+id/button6" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
	</LinearLayout>
	<LinearLayout android:layout_height="wrap_content"
		android:id="@+id/linearLayout3" android:layout_width="match_parent">
		<Button android:text="7" android:id="@+id/button7" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="8" android:id="@+id/button8" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
		<Button android:text="9" android:id="@+id/button9" style="@style/btn_custom"
			android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
	</LinearLayout>
</LinearLayout>

備考

  • ボタン9個にstyleを指定するのは面倒なので、実際にはthemeを使うべきだと思います。今回は、themeで指定しようとしたらなぜかpressedの画像がうまく適用されなかったので、styleでの指定にしました。もしかしたら、selectorの記述にどこかまずいところがあるのかもしれません。
  • 画像のグラデーションが、伸縮で汚く見えてしまっています。9patchでの指定の仕方によっては改善できるのかも。あるいはgradientを使う?

あわせて読みたい

Android Layout Cookbook 第2章カスタマイズ 1 独自の画像でボタンを作る(p.054)