view 自定义组件 --- 水滴组件
继承View可以制作出单独的组件,自己有特色的事件:
需要重写几个方法:
1. 构造器;一个是参数含有Context和另一个AttributeSet context的构造器一般用于在Java代码中new的时候用到,而attributeset则用于在xml中写一些控件属性时候用到;另外我们可以在android工程中的values目录下编写一个attribut.xml文件,里面主要在<declare-styleable>里面填写一些组件的属性,如字体大小/背景颜色等;在代码中用Context的obtainStyledAttributes读取出来
2. 重写onMeasure方法 用于测量组件的框高
3. 重写onLayout方法 用于定位组件的位置
4. onDraw() 重新绘制我们的组件
5. 如果需要对组件的做一些事件响应,我们可以重写onTouchEvent方法
需要用到几个常用的方法:
invalidate 重新调用ondraw方法
requestLayout 重新调用Layout布局过程
forceLayout 标志view下一次重绘之间先调用一下layout布局方法
自定义水滴组件:
package com.jack.waterview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
public class WaterView extends View{
/************************************************
* 水波纹demo 点击出现水波纹
*
*/
private static final String TAG = "WATER VIEW";
private static final int MAX_APHLA = 255;
private int alpha;
private int radius;
private int xDown = 540;
private int yDown = 780;
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);
/*View buttonView = this.get;
buttonView.measure(buttonView.getLayoutParams().width, buttonView.getLayoutParams().height);
Log.i(TAG, "width="+buttonView.getLayoutParams().width+" height="+ buttonView.getLayoutParams().height+" width1="+widthMeasureSpec+" height1="+heightMeasureSpec);
*/Log.i(TAG, "onMeasure");
}
/*
//布局位置 arg分别是坐标位置 zuo shang you xia 0 0 1080 1560
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
View buttonView = this.getChildAt(0);
buttonView.layout(540, 780, 900, 1000);
//buttonView.layout(arg1, arg2, arg3, arg4);
Log.i(TAG, "arg1="+arg1+" arg2="+ arg2+" arg3="+arg3+" arg4="+arg4);
}
*/
//draw方法,画出我们需要的效果
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Log.i(TAG, "onDraw");
//canvas.drawCircle(xDown, yDown, 15, paint);
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) {
// TODO Auto-generated method stub
switch(msg.what){
case 0:
flushState();
invalidate(); //系统方法 调用ondraw
Log.i(TAG, "handleMessage");
if(alpha > 0){
myHander.sendEmptyMessageDelayed(0, 50);
}
break;
default:
break;
}
}
};
//刷新圆圈的画笔尺寸
private void flushState(){
radius += 5;
alpha -= 10;
if(alpha <= 0){
alpha = 0;
}
width = radius / 4;
paint.setAlpha(alpha);
paint.setStrokeWidth(width);
}
}