EditText の見た目を変更する(2)

前回は、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 の見た目を変更
特に遅くなった感じもしないし、悪くなさそう。ただ、ちょっとなんて言うんでしょう。元のデザインのように、へこんだ感じがあんまりしない気がします。そこはセンスを磨くということで・・・。

次回は、EditText.java と、スーパークラスのコードを見ながら答え合わせをしてみます。


EditText の見た目を変更する(2)」への3件のフィードバック

  1. dsl 投稿作成者

    onMeasure を利用していたが、バックグラウンドを描画するという目的であれば onSizeChanged の方がよいかもしれない。

  2. rome

    古い記事ですが気になったので.
    9patchを使うのが一番簡単かと

  3. dsl 投稿作成者

    rome さん、ありがとうございます。9patch を使う方が汎用性もありますね。9patch で同じようにチャレンジしてみます!
    この記事を書くときも9patch の利用を考えたのですが、へこみの部分のグラデーションが綺麗に伸ばせなかったので(というほど今も綺麗ではないのですが)、安直に自分で描画する方を選んでしまいました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.