前回は、onDraw(Canvas canvas) で、毎回「角丸 + へこみ」の画像を生成して描画することはできないところまで記述した。onDraw(Canvas canvas) メソッドでオブジェクトを生成しようとすると、Eclipse で警告が表示されるし、警告を無視して動作させると GC が頻繁に発生して動作は非常に遅い。そこで、onMeasure(int widthMeasureSpec, int heightMeasureSpec)メソッドで、Drawable をあらかじめ生成しておくことにした。
public class HogeEditText extends EditText {
/** バックグラウンド */
private BitmapDrawable background;
// EditText と同じ引数でコンストラクターを作成
@Override
protected void onDraw(Canvas canvas) {
background.draw(canvas);
super.onDraw(canvas);
}
@Override
public void onDetachedFromWindow() {
background = null;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
createBackground(widthMeasureSpec, heightMeasureSpec);
}
private void createBackground(int widthMeasureSpec, int heightMeasureSpec) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
if (null != background
&& (background.getBitmap().getWidth() == width && background
.getBitmap().getHeight() == height)) {
return;
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(bitmap);
// 「角丸 + へこみ」の画像を生成する処理
background = new BitmapDrawable(getResources(), bitmap);
background.setBounds(0, 0, background.getBitmap().getWidth(),
background.getBitmap().getHeight());
}
}
全体のコードを載せるとちょっと長いので、必要な部分のみにした。実際にやってみると、onMeasure(int widthMeasureSpec, int heightMeasureSpec)メソッドは複数回呼ばれることがわかったので、高さと幅が変わった場合のみ、バックグラウンド用の Drawable を再生成するようにしてみた。
onDraw(Canvas canvas)メソッドでは、バックグラウンド用の Drawable で描画し、最後に super(canvas)としている。描画しなければならないのは、onDraw(Canvas canvs) メソッドで「角丸 + へこみ」の画像を生成して表示する場合と変わらないが、オブジェクトを生成しないし、画像を描画するだけの処理なので負荷は低いはずだ。
実際に動かしてみると・・・

特に遅くなった感じもしないし、悪くなさそう。ただ、ちょっとなんて言うんでしょう。元のデザインのように、へこんだ感じがあんまりしない気がします。そこはセンスを磨くということで・・・。
次回は、EditText.java と、スーパークラスのコードを見ながら答え合わせをしてみます。
onMeasure を利用していたが、バックグラウンドを描画するという目的であれば onSizeChanged の方がよいかもしれない。
古い記事ですが気になったので.
9patchを使うのが一番簡単かと
rome さん、ありがとうございます。9patch を使う方が汎用性もありますね。9patch で同じようにチャレンジしてみます!
この記事を書くときも9patch の利用を考えたのですが、へこみの部分のグラデーションが綺麗に伸ばせなかったので(というほど今も綺麗ではないのですが)、安直に自分で描画する方を選んでしまいました。