他の方がどうやってるかが気になるんです
どういうこと
Androidのデフォルトテンプレート (holo lightのやつ) を使ってButtonを配置すると、backgroundに標準で指定されるbtn_default_holo_lightテーマが軒並み隙間を持ってるのです。
理由は9patchにその隙間自体が描画されているからです。
marginやpaddingを0dpにしてもこの隙間自体は消えません (後述するマイナスのdpであれば一応消せます)
この隙間を適正な方法で削りたいのですが、9patchなpngは何種類もありまして、面倒だなぁ、削るツール欲しいなぁ、と。
一応Pythonでツール作った
今回必要だった機能だけ盛り込んだPythonツールを作ってみました。
概要としては以下の通り
- subprocess.PopenでImageMagick関連のツールを叩く
- convertとmontageを使いました
- 全体を5x5に分解した時の(0,0)(2,0)(4,0)(0,2)(2,2)(4,2)(0,4)(2,4)(4,4)の3x3を使います。
- 言い換えると、隙間に相当する1・3列と1・3行をふっとばします
- (0,0)(4,0)(0,4)(4,4)は何となく残しただけ。意味はないです
- 切り取る部分、残す部分のピクセルは各dpi決め打ち
- 1〜3列、1〜3行のピクセルサイズを固定の辞書構造に詰め込みました
- PIL使って今回の9patchのエッジのRGB=255,0,0なところを判定すれば自動化はできそうですが、面倒なのでスキップ
- という作業を(mdpi, hdpi, xhdpi, xxhdpi) x (normal, pressed, disabled, focused, disabled_focused) に適用する
ここまでにも若干の紆余曲折はありますが、とりあえずこれで期待する「隙間のない」9patch pngは完成します。
なお、どちらかというと、今回はAndroidというよりこのツールを作る上で使ったImageMagick系のツールの挙動を調べるのに四苦八苦しました。
今更だけど、超高機能なのな……
作った画像を利用するdrawable xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Apache2 :-)-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal_holo_light_cropped" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_disabled_holo_light_cropped" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed_holo_light_cropped" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_focused_holo_light_cropped" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal_holo_light_cropped" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_disabled_focused_holo_light_cropped" />
<item
android:drawable="@drawable/btn_default_disabled_holo_light_cropped" />
</selector>
ところで、英語としてcroppedは正確ではないのでは……とふと思ったが我慢だ
でも誰かやってそうじゃね?
最後まで疑問だったのは、この程度のことは誰かやってるんじゃねーか、という話ですね。
この話題ってば非常に古いものなので、ヘタしたらデフォルトのテーマにあったり……見てませんけど :-P
-4dpとか
paddingでマイナスと値を指定しても一応隙間削れますが、これって良いことだっけ、という別の疑問も。
結構最終手段だった記憶なんですが、なんというか色々知らないことが多いですね。
ところで赤色による隙間の明示は9patch共通ルール?
9patchではエッジ1pixel領域でメタ情報を詰め込みますが、今回ボタンの画像を見ていて赤色のマーカもついているのに気づきました。
こちら、draw9patchやAndroid本体では多分完全に無視されるのですが、何かもっとリッチなツールで自動判定してくれるんでしょうか。
まとめ
- デフォルトのボタンテーマには隙間があり、paddingやmarginで削ることも出来ないことはないが汚い
- background経由で使われる9patch png向けのツールを作った
- ベストな方法は結局何だったんだろう
追記: もらったコメント集
shapeじゃだめなん?
いいと思います!というか完全に忘れてました。
ただ、ボタンっぽくするのはそれなりに大変かもしれません
Red Tickはなんか特定のLayout (GridLayout?) で参照されたはず
何かに使われることがあるということはAndroid的に何かサポートしてるってことなのかしら。
そもそもGridLayoutって割と最近ですよねぇ。ということは、割と最近そういうヒューリスティクスを追加したのかしら。
tools:ignore="HardcodedText"
で警告消せるよ
この記事の初期では以下のような画像を使っていました。各ボタンの警告はandroid:text="1"
などと文字列をレイアウトに直書きしていたからです。正しくはstrings.xmlを使います。
うっほ! Android Tools すげぇ!