自定义组件view,调用了invalidate();却没有执行ondraw方法

帅气好男人_Jack 2015-08-10 12:39:52
根据网上的例子做了一个水波纹的demo,但是发现调用invalidate();没有执行ondraw方法,不知道是什么原因;刷行界面主要是用handler来实现的,代码如下:

public class WaterView extends View{

private static final String TAG = "WATER VIEW";
private static final int MAX_APHLA = 255;
private int alpha;
private int radius;
private int xDown;
private int yDown;
private Paint paint; //画笔
private float width;

//AttributeSet一些列属性的集合接口 xml里面的尺寸属性
public WaterView(Context context,AttributeSet attrs) {
super(context,attrs);
// TODO Auto-generated constructor stub
Log.i(TAG, "MainActivity");

alpha = 0;
radius = 0;
initPaint();
}

private void initPaint(){
Log.i(TAG, "initPaint");
paint = new Paint();

paint.setAntiAlias(true); //设置标志位ANTI_ALIAS_FLAG false为清除该标志位,该标志位的作用平滑边缘,防止锯齿状边缘
paint.setStrokeWidth(width); //设置画笔的宽度,0表示画笔为一个像素点款
paint.setStyle(Paint.Style.STROKE); //设置环形方式绘制
paint.setAlpha(alpha);

Log.i(TAG, "alpha is: "+ paint.getAlpha());
paint.setColor(Color.RED);

}

//自定义控件需要指定它的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.i(TAG, "onMeasure");
}

//draw方法,画出我们需要的效果
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Log.i(TAG, "onDraw");
canvas.drawCircle(xDown, yDown, radius, paint);

}

//touch点击事件
@Override
public boolean onTouchEvent(MotionEvent event) {

Log.i(TAG, "onTouchEvent");
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
radius = 0;
alpha = MAX_APHLA;
width = radius / 4;
xDown = (int)event.getX();
yDown = (int)event.getY();

myHander.sendEmptyMessage(0);
break;

case MotionEvent.ACTION_UP:
break;

default:
break;

}


return true;
}

private Handler myHander = new Handler(){

@Override
public void handleMessage(Message msg) {
Log.i(TAG, "handleMessage");
// TODO Auto-generated method stub
switch(msg.what){
case 0:
flushState();
invalidate(); //系统方法 调用ondraw

if(alpha > 0){
myHander.sendEmptyMessageAtTime(0, 100);
}

break;

default:
break;

}
}

};

//刷新圆圈的画笔尺寸
private void flushState(){
radius += 5;
alpha -= 10;
if(alpha <= 0){
alpha = 0;
}
width = radius / 4;
paint.setAlpha(alpha);
paint.setStrokeWidth(width);
}


}

在Activity里面直接显示xml界面,xml里面有我自定义的组件,发现点击后没有水波纹效果,并且打印日志输出,发现只调用了一次ondraw;
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/l1"
android:orientation="vertical" >

<com.jack.waterview.WaterView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/test"/>
</LinearLayout>


日志输出:
多次handler 发送消息 却只有一次ondraw调用,这是为何?

...全文
1388 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hank_er001 2017-07-06
  • 打赏
  • 举报
回复
强制重绘 requestLayout();
  • 打赏
  • 举报
回复
引用 6 楼 u013549534 的回复:
我也遇到了,不知道怎么回事,求解
方法写错了 handler里面的延迟方法写错了
new___________ 2015-09-03
  • 打赏
  • 举报
回复
我也遇到了,不知道怎么回事,求解
  • 打赏
  • 举报
回复
引用 3 楼 只为搞笑的回复:
[quote=引用 2 楼 jackzhouyu 的回复:] 顶一个月,快来看看啊
晕 我不是回答你了么,别搞笑[/quote] 我用的是delay啊 应该就是延迟发送吧,attime是在某个时刻发送,这个不是我想要的啊
只为搞笑 2015-08-10
  • 打赏
  • 举报
回复
引用 2 楼 jackzhouyu 的回复:
顶一个月,快来看看啊
晕 我不是回答你了么,别搞笑
  • 打赏
  • 举报
回复
顶一个月,快来看看啊
只为搞笑 2015-08-10
  • 打赏
  • 举报
回复
哥们,方法用错了,myHander.sendEmptyMessageDelayed(0, 100);你应该是想用这个方法来延迟发送吧,sendEmptyMessageAtTime指的是在某个时间调用,参数时这个时间的时间戳,然而100这个时间是1970年的事了,所以他马上就调用了,但是你的上一次刷新还没结束,所以他就不给你刷新了,所以你看到的是全部调用完成后才刷新了。

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧