9patchを覚えよう!

角丸が綺麗に表示されない!

ボタンを作りました!
角丸のボタンです。

早速ボタンの背景に設定しました。

なんてこったい
設定するボタンが大きすぎて背景画像が引き伸ばされてしまいます。

9patchを使おう!

そこで9patchの出番です。
9patchは、画像よりモノが大きかった場合(今回は画像よりボタンが大きかった)
引き伸ばす部分を指定することで、画像の崩れを無くす事ができるのです!
Fireworksでいう所の9スライスという機能に似ています。
先ほどのボタン画像に9patchの処理を施してみます。

できました!
上側と左側に黒い1ピクセルが見えますでしょうか?
ちょっと拡大します。

拡大したのでボケてますが、これなら分かりますね。
9patchは上下左右に、アルファ無しの黒(#000000)の印を付けることで伸ばす部分を指定します。
上下左右それぞれ意味があります。
上と左の印は必須です。
下と右の印は省略することができます。
下と右の印の説明は後でやります。

図解9patch

さきほどの画像を解説すると

上に指定したピクセルの列(赤)が

横に伸びる時にコピーされます。

左に指定したピクセルの行(青)が

縦に伸びる時にコピーされます。
こうやって角丸部分が拡大されないようにします。
端末に設定してみましょう。

綺麗に角丸が表示されました。
さらに、どの部分にコピーされているのか確認したいため、こんな画像も用意してみました。

端末で表示してみましょう。

なるほどー、さっきのサンプルみたいにコピーされました。

さらに挙動を調べる

通常9patchの上と左の指定は1ピクセルだけで済みますが、実際には複数ピクセル指定することができます。
端末で表示させて挙動をたしかめてみましょう。

たとえば2ピクセル指定した場合はどうなるんでしょう。
端末で表示して見てみます。

半分ずつコピーされました。
おもしろいですね。

次はこんな画像はどうでしょう。

各々近いところを補うんですかね。

さらに活用する

挙動が分かれば、それを利用します。

この画像を使って

こんな風に表示したり*1

この画像を使って

こんな風に表示したり*2

グラデーションなら左側をほとんど塗っちゃってもいいんじゃないでしょうか

段差が見えちゃってますが、多少の拡大ならごまかせます。


ベタ塗りなのにこういう9patchの指定の仕方をしている人がいて、本当に理解しているのかなーって心配になります…。
ちゃんと表示はされるんだけどね…。

文字が変な位置に表示される

ボタンにはラベルが必要です。
ボタンを押した時にどんな機能が働くのかを、ラベルの文字によって表現しましょう。
今回は"こんにちは!"というラベルにします。
きっと押したら"ぽぽぽぽーん!"と音が鳴るに違いありません。
さっき作ったボタンにラベルを表示するよう変更してみます。

こんにちは!って表示されたけど、位置がおかしいです。
下に表示しているデフォルトのボタンではセンタリングされているのに、今回作ったボタンは変な位置に表示されています。

さらに9patch

これも9patchの機能を使って解決します。
上と左の印を使う事によって伸ばす部分を指定しましたが、
下と右の印を使う事によってコンテンツの位置を指定することができます。
ボタンの画像に対してコンテンツの位置を指定してみます。

できました!
例によって拡大します。

下と右に黒いピクセルがたくさんあるかと思います。
解説すると

下の黒いピクセルの列(赤)と
右の黒いピクセルの行(青)の
交わった場所(紫)がコンテンツの入る場所になります。
今回だと文字列の入る場所です。
端末で表示してみましょう。

ちゃんとセンタリングされました。
さっきの赤/青の画像でも表示してみましょう。

ちゃんと紫のところにラベルが表示されています。

さらに挙動をしらべる

調べようかと思ったのですが
何もできません。
下と右はこれですべてみたいです。

例えばこんな画像を用意して端末で表示してみようかと思ったのですが
eclipseさんに怒られてしまい、コンパイルが通りません。

さらに活用する


この画像を使って

こんな風に表示したり

この画像を使って

こんな風に表示したりできます。

9patchが苦手な画像

9patchには苦手な画像があります。
たとえば

ストライプ*3

グラデーション
例に出しましたが、段差が見えてしまうのでオススメできません。

その他連続した柄*4
他にもいろいろパターンはあると思うので、想像しながら作りましょう。
AndroidSDKの中に入ってるdraw9patchというツールを使うと、どういう風に表示されるか見ながら9patchのマークを付ける事ができます。
慣れないうちはそれを使うのも手でしょう。*5

さらに9patchを理解する

読むだけだと完全に理解はできません。
これ以上は実際に作って、端末に表示させてみて、挙動を自分で確かめてみるといいと思います。

その他9patch記事

Draw 9-patch | Android Developers 
http://developer.android.com/guide/developing/tools/draw9patch.html
公式の9patch解説
Draw 9-patch - ソフトウェア技術ドキュメントを勝手に翻訳
https://sites.google.com/a/techdoctranslator.com/jp/android/developing/tools/draw9patch
公式の9patch解説の日本語翻訳
9-patch - 3156note 
https://sites.google.com/site/3156note/home/android/9-patch
draw9patchの使い方を詳しく解説
チュートリアル:9patchで画像を作る « Tech Booster 
http://techbooster.jpn.org/andriod/environment/3996/
draw9patchの使い方を詳しく解説
draw9patch で NinePatch をつくる方法 - Hacking My Way 〜 itogのhack日記
http://d.hatena.ne.jp/itog/20100209/1265684439
draw9patchの使い方を詳しく解説

まとめ

  • 単純に拡大されたくない時は9patchを使う。
  • コピーされる場所を指定するには上と左に9patchのマークをつける。
  • 中に何かコンテンツを入れる時は下と右に9patchのマークをつける。
  • どんな画像になるか想像しながら作る。

*1:xmlで指定することにより、ボタンとアイコン(ハート、星)を分離することができます。分離できた方がデザイナさんもプログラマーさんも幸せなので、そちらを使った方がいいです。

*2:xmlで指定することにより、ボタンとアイコン(ハート、星)を分離することができます。分離できた方がデザイナさんもプログラマーさんも幸せなので、そちらを使った方がいいです。

*3:9patchではなく、これを使うと解決できるかもしれません http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap

*4:9patchではなく、これを使うと解決できるかもしれません http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap

*5:個人的にはすごく使いづらいのでFireworksで全部描いちゃってます