月別アーカイブ: 2013年4月

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 と、スーパークラスのコードを見ながら答え合わせをしてみます。