画线运行成功的代码!!
package com.example.lockpattermview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class LockPatternView extends View {
//选中点的数量
private static final int POINT_SIZE=5;
//矩阵
private Matrix matrix=new Matrix();
//画笔
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
//9's point
private Point[][] points=new Point[3][3];
//whether init
private boolean isInit,isSelect,isFinish,movingNoPoint;
private float width,height,offsetsX,offsetsY,bitmapR,movingX,movingY;
private Bitmap pointNormal,pointError,pointPressed,linePressed,lineError;
//按下点集合
private List<Point> pointList= new ArrayList<Point>();
public LockPatternView(Context context){
super(context);
}
public LockPatternView(Context context,AttributeSet attrs){
super(context,attrs);
}
public LockPatternView(Context context,AttributeSet attrs,int defStyleAttr){
super(context,attrs,defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
if( !isInit){
initPoints();
}
//画点
points2Canvas(canvas);
//画线
if(pointList.size()>0){
Point a=pointList.get(0);
//绘制9宫格里坐标点
for(int i=0; i<pointList.size();i++){
Point b=pointList.get(i);
line2Canvas(canvas,a,b);
a=b;
}
//绘制鼠标坐标点
if(movingNoPoint){
line2Canvas(canvas, a, new Point(movingX,movingY));
}
}
}
//将点绘制到画布
private void points2Canvas(Canvas canvas){
for(int i=0; i<points.length; i++){
for(int j=0; j<points[i].length;j++){
Point point =points[i][j];
if(point.state== Point.STATE_PRESSED){
canvas.drawBitmap(pointPressed, point.x-bitmapR,point.y-bitmapR, paint);
}else if(point.state== Point.STATE_ERROR){
canvas.drawBitmap(pointError, point.x-bitmapR,point.y-bitmapR, paint);
}else{
canvas.drawBitmap(pointNormal, point.x-bitmapR,point.y-bitmapR, paint);
}
}
}
}
//画线
private void line2Canvas(Canvas canvas , Point a , Point b){
//线的长度
float lineLength=(float) Point.distance(a, b);
float degrees=getDegrees(a,b);
canvas.rotate(degrees,a.x,a.y);
if(a.state==Point.STATE_PRESSED){
matrix.setScale(lineLength/linePressed.getWidth(), 1);
matrix.postTranslate(a.x-linePressed.getWidth()/2 , a.y-linePressed.getHeight());//平移
canvas.drawBitmap(linePressed,matrix,paint);
}else{
matrix.setScale(lineLength/lineError.getWidth(), 1);
matrix.postTranslate(a.x-lineError.getWidth()/2 , a.y-lineError.getHeight());
canvas.drawBitmap(lineError,matrix,paint);
}
canvas.rotate(-degrees,a.x,a.y);
}
//初始化点
private void initPoints() {
//1.获取布局宽高
width=getWidth();
height=getHeight();
//2.偏移量
//横屏
if(width>height){
offsetsX =(width-height)/2;
width=height;
}
//竖屏
else{
offsetsY=(height-width)/2;
height=width;
}
//3 图片处理
pointNormal=BitmapFactory.decodeResource(getResources(),R.drawable.oval_normal);
pointPressed=BitmapFactory.decodeResource(getResources(),R.drawable.oval_pressed);
pointError=BitmapFactory.decodeResource(getResources(),R.drawable.oval_error);
linePressed=BitmapFactory.decodeResource(getResources(),R.drawable.line_pressed);
lineError=BitmapFactory.decodeResource(getResources(),R.drawable.oval_error);
//点的坐标
points[0] [0]=new Point(offsetsX+width/4,offsetsY+width/4);
points[0] [1]=new Point(offsetsX+width/2,offsetsY+width/4);
points[0] [2]=new Point(offsetsX+width-width/4,offsetsY+width/4);
points[1] [0]=new Point(offsetsX+width/4,offsetsY+width/2);
points[1] [1]=new Point(offsetsX+width/2,offsetsY+width/2);
points[1] [2]=new Point(offsetsX+width-width/4,offsetsY+width/2);
points[2] [0]=new Point(offsetsX+width/4,offsetsY+width-width/4);
points[2] [1]=new Point(offsetsX+width/2,offsetsY+width-width/4);
points[2] [2]=new Point(offsetsX+width-width/4,offsetsY+width-width/4);
//图片半径
bitmapR=pointNormal.getWidth()/2;
//6.初始化完成
isInit=true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
movingNoPoint=false;
isFinish=false;
movingX=event.getX();
movingY=event.getY();
Point point=null;
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
resetPoint();
//鼠标点是否为九宫格点
point=checkSelectPoint();
if(point!=null){
isSelect=true;
}
break;
case MotionEvent.ACTION_MOVE:
if(isSelect){
point=checkSelectPoint();
if(point==null){
movingNoPoint=true;
}
}
break;
case MotionEvent.ACTION_UP:
isFinish=true;
isSelect=false;
break;
}
//选中重复检查
if( !isFinish && isSelect &&point !=null){
//交叉点
if(crossPoint(point)){
movingNoPoint=true;
//新点
}else{
point.state=Point.STATE_PRESSED;
pointList.add(point);
}
}
//绘制结束
if(isFinish){
//绘制不成立
if(pointList.size()==1){
resetPoint();
}
//绘制错误
else if(pointList.size()<POINT_SIZE && pointList.size()>2)
{
errorPoint();
}
}
//刷新View
postInvalidate();
return true;
}
//交叉点
private boolean crossPoint(Point point){
if(pointList.contains(point)){
return true;
}
else{
return false;
}
}
/*
* 设置绘制不成立
* */
public void resetPoint(){
for(int i=0; i<pointList.size(); i++){
Point point =pointList.get(i);
point.state=Point.STATE_NORMAL;
}
pointList.clear();
}
public void errorPoint(){
for(Point point : pointList){
point.state=Point.STATE_ERROR;
}
}
//检查是否选中
private Point checkSelectPoint(){
for(int i=0; i<points.length; i++){
for(int j=0; j<points[i].length; j++)
{
Point point= points[i] [j];
if(Point.with(point.x,point.y,bitmapR,movingX,movingY)){
return point;
}
}
}
return null;
}
public float getDegrees(Point a ,Point b){
float ax=a.x;
float ay=a.y;
float bx=b.x;
float by=b.y;
float degrees=0;
float dun;
if (ax == bx){ //90度或270度
if(by > ay){ //在y轴下边
degrees = 90;
} else if(by < ay){
degrees = 270;
}
}else if(ay == by){ // 0 度或180度
if (ax>bx){
degrees = 180;
}else if(ax<bx){
degrees = 0 ;
}
}else {
dun=(b.y-a.y)/(b.x-a.x);
degrees= (float) ((float)Math.atan(dun)/Math.PI*180);
if (a.y<b.y&&a.x>b.x){
degrees=180+degrees; //270°-360°
}
if (a.x>b.x&&a.y > b.y) { //180°-270°
degrees=180+degrees;
}
}
return degrees;
}
private float switchDegrees(float x, float y){
//弧度转化为角度
return (float)Math.toDegrees(Math.atan2(x,y));
}
/*
* 定义点
*/
public static class Point{
// normal
public static int STATE_NORMAL=0;
//select
public static int STATE_PRESSED=1;
//wrong
public static int STATE_ERROR=2;
public float x,y;
public int index=0, state=0;
public Point(){}
public Point(float x, float y){
this.x=x;
this.y=y;
}
//两点之间的距离
public static double distance(Point a,Point b){
//x轴的平方加上y轴的差的平方,让和平方
return Math.sqrt(Math.abs(a.x-b.x)* Math.abs(a.x -b.x ) + Math.abs(a.y-b.y )*Math.abs(a.y-b.y));
}
//点之间的距离
public static boolean with(float pointX, float pointY, float r, float movingX, float movingY){
//开方
return Math.sqrt( (pointX-movingX) * (pointX-movingX) + (pointY-movingY) * (pointY-movingY) )<r;
}
}
}