Tips : ImageButton で画像を使わずにタッチのハイライトをする

久しぶりの更新です。 最近Androidのアプリ制作に打ち込んでいたため、ブログ更新に手が回りませんでした。

では、Androidアプリ制作で利用した小ネタを書き留めておきたいと思います。

ImageButtonパーツ

ImageButtonパーツは、Buttonの表示にイメージを利用できる便利なパーツです。 (Bitmapリソースの管理がよくないらしいですが、、、)

レイアウトXMLから利用するコード例はこんな感じになります。

1
2
3
4
5
6
7
<ImageButton
      android:id='@+id/button'
      android:layout_width='wrap_content'
      android:layout_height='wrap_content'
      android:scaleType='centerInside'
      android:background='@null'
      android:src='@drawable/image' />

android:backgroundがボタン部分、android:srcがボタンのシルク部分にあたる指定になります。 普通に使うとandroid:srcでイメージを指定する形になりますが、これだとAndroidのデフォルトのボタンスタイルの上に、指定イメージが乗るような見た目になるのでちょっと期待と異なってしまいます。

background="@null"とすると、デフォルトのボタン部分が消えるので、イメージだけでボタンパーツを見せることができます。 しかし、こうすると、タッチ時のフィードバック(ボタンタッチ時のハイライト等)がなくなってしまいます。

ImageButtonのタッチフィードバック

ボタンを押したときは、UIの操作性を考慮して、即座のインタラクションが欲しいところです。

タッチのフィードバックの実装には、selectorを利用します。 selectorを使ったフィードバックの方法で、もっともよくあるのは色や大きさを少し変えたボタンイメージをもう一つ用意して、タッチ時にそのイメージと入れ替える方法です。(こちらの方法はStackOverflowなどによくあるのでそちらを参照ください)

しかし、この方法を使うとボタンがたくさんあるときは、ボタン画像のペア(シルク用とハイライト用)がボタン数分必要になり、リソースが大きくなってしまします。 また、ボタンのデザインがある程度統一されていると、ちょっと輝度を落としただけの画像をボタン数用意するのは、やや冗長な感じがします。

ハイライト用のペア画像を使わないでタッチフィードバックを実装する

そこで、ハイライト用の画像を利用しない方法として、shapecolorを利用してハイライトを実装します。

まず、selectorのコードです。

1
2
3
4
5
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
    <item android:drawable='@color/gray' android:state_pressed='true'/>
    <item android:drawable='@android:color/transparent'/>
</selector>

ポイントは、android:state_pressed='true'のついていない、シルク表示時のコードです。@color/transparentとすることで利用イメージをそのまま表示しています。これで、android:state_pressed='true'で指定した要素をタッチ時にオーバーレイするだけというselectorを作ることができます。

これをImageButtonのandroid:srcに指定します。

1
2
3
4
5
6
7
<ImageButton
      android:id='@+id/button'
      android:layout_width='wrap_content'
      android:layout_height='wrap_content'
      android:scaleType='centerInside'
      android:background='@drawable/image'
      android:src='@drawable/selector' />

このとき、@drawable/image@drawable/selectorの指定はそれぞれ上記のようにします。android:backgroundにイメージ、android:srcselectorを指定することで、イメージにselectorをオーバーレイすることができます。

オーバーレイするcolorは、#80808080のようにしておきます。これで、半透過のグレーでオーバーレイすることができます。

オーバーレイする効果を変更する

これまでのコードでは、ボタン指定領域いっぱいに#80808080をオーバーレイするだけでした。

利用しているイメージが、領域いっぱいに四角形を描くようなイメージであればこれで問題ないと思いますが、少しマージンが埋め込まれたイメージや、サークルなどの形状のイメージだと、ハイライトとイメージの形状がずれておかしく見えてしまいます。

そこで、colorの代わりにshapeを利用してみます。 まず、shapeのコードです。

1
2
3
4
5
6
7
<?xml version='1.0' encoding='utf-8'?>
<shape
    xmlns:android='http://schemas.android.com/apk/res/android'
    android:shape='oval'>
   <solid
       android:color='#80808080'/>
</shape>

android:shape="oval"を指定し、その中を#80808080で塗りつぶします。 そしてこれを、先ほどのselectorに指定します。

1
2
3
4
5
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
    <item android:drawable='@drawable/circle' android:state_pressed='true'/>
    <item android:drawable='@android:color/transparent'/>
</selector>

すると、ボタン領域に接するように収まる円形のハイライトがかけられます。

まとめ

この方法を利用すると、ハイライト用の画像を用意せず、また複数のボタンでselectorを使いまわせるため、実装・デザイン両方で効率的にImageButtonを作成できます。

ただ、複雑な形状のボタンなどになるとshapeでも対応できなくなると思いますので、非常に凝ったボタンデザインのときには、ハイライト画像を利用するなど使い分けをすると良いかと思います。

Effective Android Amazonで見る
Built with Hugo
テーマ StackJimmy によって設計されています。