*
自定义控件:
*
构造方法:一般都至少要重写两个。一个用于动态创建,一个用于在布局中适用
*/
*/
public class
MyView
extends
View{
//
在代码中动态创建控件要存在的构造方法
public
MyView(Context context) {
super
(context);
Log.
i
(
"info"
,
"====MyView1======="
);
}
//
这个构造方法必须有。只要这个自定义控件要在布局中适用,就必须存在
public
MyView(Context context, AttributeSet attrs) {
super
(context, attrs);
Log.
i
(
"info"
,
"====MyView2======="
);
}
//canvas
:当前控件要绘制到的画布
@Override
1.protected void
onDraw(Canvas canvas)
{
super
.onDraw(canvas);
//
创建一个画笔
Paint paint =
new
Paint();
paint.setColor(Color.
RED
);
//
设置画笔的颜色
paint.setTextSize(
20
);
//
设置字体大小
paint.setStrokeWidth(
30
);
//
设置画笔的宽度
paint.setAntiAlias(
false
);
//
开启抗锯齿
//paint.setStyle(Paint.Style.STROKE);
int
width = getWidth();
int
height = getHeight();
//
画线:只需要找到开始和结束的坐标
//
开始的
x
坐标 开始的
y
坐标
//
结束的
x
坐标 结束的
y
坐标
canvas.drawLine(
0
,
0
,width,
0
,paint);
//
上边的一条线
canvas.drawLine(
0
,
0
,
0
,height,paint);
//
左边的
canvas.drawLine(width,
0
,width,height,paint);
//
右边
canvas.drawLine(
0
,height,width,height,paint);
//
下边
//
对角线
//
画圆
:
圆心的坐标,半径的大小
//
圆心的
x
坐标 圆心的
y
坐标 半径
paint.setColor(Color.
BLACK
);
paint.setStyle(Paint.Style.
STROKE
);
//
设置画笔的样式:
STROKE
(空心)
fill
(填充,默认)
paint.setStrokeWidth(
10
);
paint.setAntiAlias(
true
);
canvas.drawCircle(width/
2
,height/
2
,
50
,paint);
//
画矩形
:
矩形的左上角的和右下角的坐标
//
左上角的
x
坐标 左上角的
y
坐标
//
右下角的
x
坐标 右下角的
y
坐标
paint.setStyle(Paint.Style.
STROKE
);
canvas.drawRect(
0
,
0
,
200
,
100
, paint);
Rect rect =
new
Rect(width-
200
,height-
100
,width,height);
canvas.drawRect(rect,paint);
//
画圆角矩形
:
在画矩形的基础上多了圆角弧度
//canvas.drawRoundRect(200,100,400,200,30,30,paint);
//
画图片
:
要画的图片的资源。图片的左上角的坐标
//
图片资源 放置图片的左上角的
x
坐标 放置图片的左上角的
y
坐标
Bitmap bitmap = BitmapFactory.
decodeResource
(getResources(), R.mipmap.
ic_launcher
);
canvas.drawBitmap(bitmap,
300
,
0
,paint);
//
画文本
:
文字的内容。(
0
,
0
):文字
x
从最左边的文字 文字高度的
1/2
处
paint.setStrokeWidth(
1
);
paint.setColor(Color.
GREEN
);
canvas.drawText(
"
描绘的文字内容
"
,
0
,
20
,paint);
}
//
测量当前控件的宽高值
//widthMeasureSpec
:由控件的宽的测量模式和宽度组成的一个数据。从这个数据中获取到宽度的测量模式和控件的宽
//heightMeasureSpec
:由控件的高的测量模式和高度组成的一个数据。从这个数据中获取到高度的测量模式和控件的高
@Override
2.protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super
.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.
i
(
"info"
, widthMeasureSpec +
"====onMeasure======="
+ heightMeasureSpec);
//
获取到宽度的测量模式
int
widthMode = MeasureSpec.
getMode
(widthMeasureSpec);
//
获取到高度的测量模式
int
hightMode = MeasureSpec.
getMode
(heightMeasureSpec);
//int widthSize = MeasureSpec.getSize(widthMeasureSpec);
if
(widthMode == MeasureSpec.
EXACTLY
&& hightMode == MeasureSpec.
EXACTLY
){
//
当控件的宽度或者高度为一个固定的值,比如:
match_parent
或者一个具体的指定值
100dp
Log.
i
(
"info"
,
"======
控件的宽度或者高度为一个固定的值
====="
);
}
else if
(widthMode == MeasureSpec.
AT_MOST
&& hightMode == MeasureSpec.
AT_MOST
){
//
当控件的宽度或者高度为一个尽量多的值。比如:
wrap_content
Log.
i
(
"info"
,
"===
当控件的宽度或者高度为一个尽量多的值
===="
);
//setMeasuredDimension(100,100);
}
//
注意:当前获取到的控件的宽高值和布局中的控件的宽高值的单位不是一样的。所以看到的值可能不一样
int
width = MeasureSpec.
getSize
(widthMeasureSpec);
//
用来表示控件的宽度
,
默认的控件的宽度
int
height = MeasureSpec.
getSize
(heightMeasureSpec);
//
用来表示空间的高度
,
默认的控件的高度
if
(widthMode == MeasureSpec.
AT_MOST
){
width =
100
;
}
if
(hightMode == MeasureSpec.
AT_MOST
){
height =
100
;
}
//
设置当前控件的宽高值
setMeasuredDimension(width,height);
Log.
i
(
"info"
,
"
控件的宽高
"
+width +
"=="
+height);
}
//
控件的触摸事件的处理
@Override
3.public boolean onTouchEvent(MotionEvent event)
{
event.getX();
event.getY();
int
action = event.getAction();
if
(action == MotionEvent.
ACTION_DOWN
){
Log.
i
(
"info"
,
"======ACTION_DOWN======"
);
}
else if
(action == MotionEvent.
ACTION_MOVE
){
Log.
i
(
"info"
,
"=======ACTION_MOVE====="
);
}
else if
(action == MotionEvent.
ACTION_UP
){
Log.
i
(
"info"
,
"=======ACTION_UP====="
);
}
//
要接收到所处理的事件,必须返回
true
return true
;
}
}