I'm working on custom view, which have to draw custom canvas when pressed and other if not. I have basically overriden only methods onMeasure
and onDraw
. In Constructor I have set: setFocusable(true)
and setDrawingCacheEnabled(true)
public class CircularImageView extends ImageView{
//...
@Override
protected void onDraw(Canvas canvas) {
// ...
if (isPressed() || isSelected() || isFocused()){
// code when pressed
}
else{
// otherwise
}
}
}
I want this effect: view looks like pressed after onDown
and like non-pressed after onUp
/onCancel
motion event. Normally I was using <selector>
but now i have to do a little bit of work with canvas. (one draws circle around view, other some background effects)
How can I set canvas for different press states?
Thanks to pskink I was able to create complete solutions so here is it.
If you want to create custom view in which have to be your custom drawings for different touch states (pressed, selected, focused etc.) and you didn't know whether this view will be placed inside other View that can intercept touch events or the view structure is even more difficult. You should implement the behavior as follows
Drawable
isStateful()
return true value (needed to hold different states)onStateChange
method and call invalidateSelf()
if state was changed.draw
method to implement custom drawing based on drawableState (see getState
method)setImageDrawable
, setBackground
... depends on your needs)Example:
public class CircularImageView extends ImageView{
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(new CustomDrawable(
((BitmapDrawable)drawable).getBitmap()));
}
protected class CustomDrawable extends Drawable {
//
private Bitmap bitmap;
public CustomDrawable(Bitmap bitmap){
this.bitmap = bitmap;
}
@Override
public boolean isStateful() {
// always return true
return true;
}
@Override
public int getOpacity() {
// see documentation on android developers site
return PixelFormat.OPAQUE;
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public void setAlpha(int i) {
}
boolean pressed = false;
@Override
protected boolean onStateChange(int[] states) {
// simplified but working
for (int state : getState()){
if (state == android.R.attr.state_pressed ||
state == android.R.attr.state_focused)
pressed = true;
else pressed = false;
}
invalidateSelf();
return true;
}
@Override
public void draw(Canvas canvas) {
// very simplified example
canvas.drawBitmap(bitmap,0,0,paint);
circlePaint.setColor(pressed ? colorActive : colorPassive);
canvas.drawCircle(0, 0, 100, 100);
}
}
}