Android でユーザー入力値を受け取る場合は、EditText を使う。残念ながら標準の EditText は見栄えがあまりよくない。カスタマイズの方法は用意されており、たとえば角丸にしたいのであれば、以下のような XML を drawable に用意して、レイアウトの XML で「 android:background=”@drawable/background”」(background.xmlで作成した場合)と指定するだけだ。
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#bbcfc4" /> <corners android:bottomLeftRadius="5.0dip" android:bottomRightRadius="5.0dip" android:topLeftRadius="5.0dip" android:topRightRadius="5.0dip" /> </shape>
ところが今回、下図のようなデザインで入力エリアを作成したいという話になった。角丸はできるとして、少しへこんだように見えるように作らないといけない。
すぐに思いつくのは、「android:background」で背景画像にデザインで作成した画像を埋め込む方法だ。しかしこれだと、入力エリアの高さと幅が固定じゃないと角丸の大きさが崩れてしまう。HTML + CSS でリキッドデザインを行う時のように、複数の画像を組み合わせられればよいのだが・・・
少し強引だが、EditTextを継承したクラスを作って、onDraw でバックグラウンドを書いてみることにした。単純に考えると、
- setBackground() をオーバーライドして背景画像を埋め込む
- onDraw() で super.onDraw() する前に「角丸 + へこみ」の画像を生成して表示する
のどちらかで実現できそうだ。
最初の方法はあえなく撃沈した。まず、コンパイラーに怒られた。setBackground(Drawable background)は、API level 16以上が必要と言われ、setBackgroundDrawable(Drawable background)は deprecated と言われる。どうしようもない感じだが、とりあえずsetBackgroundDrawable(Drawable background)でセットしてみた。んー、変化なし。Android のコードを読んで理解しないと、このメソッドを安全かつ有用に呼べそうにない。
2番目の方法もとりあえず作ってみると・・・onDraw はフォーカスしたときや文字の入力など、描画に変更があるときに常に呼び出されるので、負荷が大きく遅くて使い物にならない。どこかのタイミングで「角丸 + へこみ」の画像を生成して、画像を表示するだけにする必要がある。ということで、onMeasure(int widthMeasureSpec, int heightMeasureSpec)あたりが良さそうと当たりをつけた。続きは次回にて。