In trying to tackle custom views, I'm attempting to work with touch events and partial invalidation. For this, it's just a row of numbers in squares spaced to fill the screen.
Now when I press on a single block, I get the block's rectangle using this:
private Rect getDirtyRegion(float e){
// The value is the slot number
mValue = ((int)e / mBlockSize);
// start X of the "stall"
int x1 = mValue * mBlockSize;
int y1 = 0;
int x2 = x1 + mBlockSize;
int y2 = getMeasuredHeight();
return new Rect(x1, y1, x2, y2);
}
It works as expected. When there's just a few on screen it works great. Here's my onTouchEvent
:
@Override
public boolean onTouchEvent(MotionEvent e){
switch(e.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "ActionDown");
setPaint(PinEntry.PAINT_PRESSED);
invalidate(getDirtyRegion(e.getX()));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
setPaint(PinEntry.PAINT_NORMAL);
invalidate();
break;
}
return true;
}
(This has been rewritten quite a few times, so the call to invalidate
without a rectangle hasn't always been the case.)
What I'm after is, when I tap on a number, it redraws to indicate a PRESSED state by whatever I do in setPaint
. When I release, reset.
When I have multiple views in a ScrollView
, however it breaks. When I press and release, or even drag outside the bound (triggering ACTION_CANCEL
), it resets. However, going back to that row causes the whole thing to invalidate as "PRESSED".
Is this a TouchEvent logic issue, a drawing issue, or some combination of my inexperience with creating custom views?
I ended up splitting it into two different classes, one for the container (parent), and another for each individual block and using the draw(Canvas)
method of the View
class.