Sunday, July 21, 2013

Android タッチ時に対象Viewに枠線をつける(特殊編)

前提:
今回取り扱う問題は以下のちょっと特殊なViewで発生した話です。通常のViewでは発生しない問題かと思います。
* 自前で拡張してドラッグ&ピンチズームアウトされる
* ドラッグやピンチに従って自領域と座標を再描写し続ける

AndroidでViewをタッチしたときに色を変えたり枠線をつけたりというのはよくある話で、selectorを用意してitemのstate_pressedとかでshapeを書くような感じになると思うのですが、今回はitemのandroid:state_xxxで対応仕切れないタッチイベントの制御をしたかったのでそれらxml群は捨て、Viewを拡張して直接onDrawをいじる事にした。


private static final BACKGROUND;
private static final BORDER;
static {
    BACKGROUND = new Paint();
    BACKGROUND.setColor(Color.argb(192, 255, 0, 0));
    BORDER = new Paint();
    BORDER.setStyle(Paint.Style.STROKE);
    BACKGROUND.setColor(Color.WHITE);
}

@Override
protected void onDraw(Canvas c) {
    super.onDraw(c);
    c.drawRect(0, 0, c.getWidth(), c.getHeight(), BACKGROUND);
    c.drawRect(0, 0, c.getWidth(), c.getHeight(), BORDER);
}


素直にこんな感じのコードを書いたのですが、いざ動かしてみるとゆっくりドラッグしたとき不規則に枠線のゴミが残る。。(昔のWindowsでマシンの応答が悪いときにウィンドウをグリグリしたときみたいな感じ)

で、該当Viewの領域はドラッグに合わせて絶えず移動しているので、移動によって枠線が自分の領域の外になってしまい、そこの部分の再描写がかからずにゴミが残ってるのではという仮説の元


@Override
protected void onDraw(Canvas c) {
    super.onDraw(c);
    c.drawRect(0, 0, c.getWidth(), c.getHeight(), BACKGROUND);
    c.drawRect(1, 1, c.getWidth()-1, c.getHeight()-1, BORDER);
}

枠線を無理矢理Viewの領域の中に入れてみたらうまくいった。快適。

No comments :

Post a Comment