4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

btn_default_XXX_holo_light.9.png の隙間を取るベストな方法は……

Last updated at Posted at 2014-03-27

他の方がどうやってるかが気になるんです

どういうこと

Androidのデフォルトテンプレート (holo lightのやつ) を使ってButtonを配置すると、backgroundに標準で指定されるbtn_default_holo_lightテーマが軒並み隙間を持ってるのです。

範囲を選択_167.png

理由は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は完成します。

範囲を選択_166.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領域でメタ情報を詰め込みますが、今回ボタンの画像を見ていて赤色のマーカもついているのに気づきました。

example_9patch.png

こちら、draw9patchやAndroid本体では多分完全に無視されるのですが、何かもっとリッチなツールで自動判定してくれるんでしょうか。

まとめ

  • デフォルトのボタンテーマには隙間があり、paddingやmarginで削ることも出来ないことはないが汚い
  • background経由で使われる9patch png向けのツールを作った
  • ベストな方法は結局何だったんだろう

追記: もらったコメント集

shapeじゃだめなん?

いいと思います!というか完全に忘れてました。

ただ、ボタンっぽくするのはそれなりに大変かもしれません

Red Tickはなんか特定のLayout (GridLayout?) で参照されたはず

何かに使われることがあるということはAndroid的に何かサポートしてるってことなのかしら。

そもそもGridLayoutって割と最近ですよねぇ。ということは、割と最近そういうヒューリスティクスを追加したのかしら。

tools:ignore="HardcodedText" で警告消せるよ

この記事の初期では以下のような画像を使っていました。各ボタンの警告はandroid:text="1"などと文字列をレイアウトに直書きしていたからです。正しくはstrings.xmlを使います。

gapped_88buttons.png

うっほ! Android Tools すげぇ!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?