自定义View
创建自定义控件步骤
继承View,重写onDraw(Canvas)方法,绘制自定义控件。
在layout_main布局文件中添加自定义View标签。
得到自定义控件的宽和高(长度以像素为单位)
this.getWidth(); this.getHeight();
Canvas画布类
绘制矢量图
绘制线段
canvas.drawLine(startX,startY,endX,endY,paint);
绘制矩形
canvas.drawRect(left,top,right,bottom,paint);
绘制圆
canvas.drawCircle(x,y,radius,paint);
绘制路径
Path path=new Path();//要想绘制折线图,把画笔设为空心path没有
path.moveTo(0,300);// 关闭
path.lineTo(100,800);
path.lineTo(500,800);
canvas.drawPath(path,paint);
绘制文字
canvas.drawText(text,x,y,paint);//文字的锚点坐标在左下角
绘Canvas.drawBitmap(bitmap,x,y,paint);//图片的锚点坐标在左上角布
canvas.save();//保存画布
canvas.clipRect(0,0,200,100);//设置裁剪区域
canvas.drawCircle(100,100,100,paint);//在画布上绘制图形
canvas.restore();//恢复画布
Paint画笔类
设置画笔颜色
paint.setColor(Color.BLACK);
消除画笔锯齿
paint.setAntiAlias(true);
设置画笔样式
//实心画笔
paint.setStyle(Style.FILL);
//空心画笔
paint.setStyle(Style.STROKE);
- 自定义View的事件监听
- 重写onTouchEvent方法,监听用户事件
- 获取用户触摸点坐标
- event.getX(); event.getY();
获取用户触摸动作
event.getAction();
用户动作
MotionEvent.ACTION_DOWN//按下
MotionEvent.ACTION_UP//松开
MotionEvent.ACTION_MOVE//移动
**注意:如果要求捕获全部动作,需要将onTouchEvent方法的返回值设置为true
刷新控件界面**
在主线程中使用
this.invalidate();//在主线程中使用刷新界面
在子线程中使用
this.postInvalidate();
实例:点击屏幕上的位置,每点击一次就得到一个圆
如图所示:
代码:
MainActivity.class
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MyView.java
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MyView extends View {
Paint paint = new Paint();
ArrayList<Point> point=new ArrayList<Point>();
int radius=50;
//保存圆心坐标
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
paint.setColor(Color.WHITE);
//画圆
for(int i=0;i<point.size();i++){
canvas.drawCircle(point.get(i).getX(),point.get(i).getY(),radius, paint);
}
}
// 当用户触摸控件时,系统调用该方法
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
// 获取触摸点坐标
Log.d("Tag", "(" + x + "," + y + ")");
// 触摸动作 (按下,松开,滑动)
//触摸动作,默认只能检测到down。
//如果想检测另外两个动作,必须将返回值改为true
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("Tag", "down");
point.add(new Point(x, y));
//发送消息,让系统自动调用onDraw方法
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("Tag", "up");
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d("Tag", "move");
}
return true;
}
}
Point.java
public class Point {
int x;
int y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}