前回は、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 の利用を考えたのですが、へこみの部分のグラデーションが綺麗に伸ばせなかったので(というほど今も綺麗ではないのですが)、安直に自分で描画する方を選んでしまいました。