我正在处理自定义视图,必须在按下时绘制自定义画布,否则必须绘制其他画布。我基本上只覆盖方法onMeasure
和onDraw
。在构造函数中,我设置了setFocusable(true)
和setDrawingCacheEnabled(true)
public class CircularImageView extends ImageView{
//...
@Override
protected void onDraw(Canvas canvas) {
// ...
if (isPressed() || isSelected() || isFocused()){
// code when pressed
}
else{
// otherwise
}
}
}
我想要这样的效果:视图看起来像onDown
之后的按下,就像onUp
/ onCancel
动作事件之后的未按下一样。通常我使用<selector>
,但现在我必须使用canvas进行一些工作。 (一个围绕视图绘制圆圈,其他一些背景效果)
如何为不同的按下状态设置画布?
答案 0 :(得分:3)
感谢pskink我能够创建完整的解决方案,所以就在这里。
如果您想创建自定义视图,其中必须是针对不同触摸状态(按下,选择,聚焦等)的自定义绘图,并且您不知道此视图是否将放置在可以拦截触摸的其他视图中事件或视图结构更加困难。您应该按如下方式实现行为
Drawable
isStateful()
返回true值(需要保持不同的状态)onStateChange
方法,如果状态已更改,请致电invalidateSelf()
。draw
方法以基于drawableState实现自定义绘图(请参阅getState
方法)setImageDrawable
,setBackground
...取决于您的需求)示例:
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);
}
}
}
答案 1 :(得分:1)
创建一个布尔值来控制何时按下视图并覆盖onTouchEvent以将其设置为true或false:
private boolean pressed;
@Override
protected void onDraw(Canvas canvas) {
// ...
if (pressed){
// code when pressed
}
else{
// otherwise
}
}
@Override
public boolean onTouchEvent(MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
pressed = true;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
pressed = false;
this.invalidate();
break;
}
}