Android 实现图形解锁
来源:互联网 发布:python实战 编辑:程序博客网 时间:2024/06/05 05:36
前一久写了一个图形锁的view,实现的难度不是很大,不过对初学者学习自定义view,觉得还是一个很好的例子吧,当然每个人实现的图形锁界面有不同的逻辑,对界面之间的连接也有不一样的控制能力。如果本文有功能没有达到读者的需求或者是与读者需求不一样的,可以自己改一下代码,都很简单
先上图片
![没有划线的时候]
![匹配错误的时候]
代码
##点的类,在里面实现draw方法。##/** * Created by sunshine */public class Point { //私有属性 private int id; private float x; private float y; private boolean isTouched; private boolean isError; private Paint paint; /** * 共有属性 */ //圆环的画笔大小 private static int STROKE_WIDTH=10; //普通颜色 private static int COLOR_DEFAULT= Color.YELLOW; //点击之后的颜色 private static int COLOR_CHOOSED=Color.GREEN; //错误之后的颜色 private static int COLOR_ERROR=Color.RED; //圆环的半径 private float radious; public Point(){} public Point(float x,float y,int id){ this.x=x; this.y=y; this.isError=false; this.isTouched=false; radious=60; paint=new Paint(); this.id=id; } public void setTouched(boolean isTouched){ this.isTouched=isTouched; } public void setIsError(boolean isError){ this.isError=isError; } public void draw(Canvas canvas){ paint.setColor(isTouched ? (isError ? COLOR_ERROR : COLOR_CHOOSED) : COLOR_DEFAULT); paint.setStrokeWidth(STROKE_WIDTH); paint.setAntiAlias(true); canvas.drawPoint(x, y, paint); paint.setStyle(Paint.Style.STROKE); canvas.drawCircle(x,y,radious,paint); } public static void setColorChoosed(int colorChoosed) { COLOR_CHOOSED = colorChoosed; } public static void setColorDefault(int colorDefault) { COLOR_DEFAULT = colorDefault; } public static void setColorError(int colorError) { COLOR_ERROR = colorError; } public static void setStrokeWidth(int strokeWidth) { STROKE_WIDTH = strokeWidth; } public void setRadious(float radious) { this.radious = radious; } public void setX(float x) { this.x = x; } public void setY(float y) { this.y = y; } public void setIsTouched(boolean isTouched) { this.isTouched = isTouched; } public float getX() { return x; } public float getY() { return y; } public int getId() { return id; } public boolean getTouchState(){ return isTouched; } public void setLocation(float x, float y) { this.x=x; this.y=y; }}
接下来就是主要的ImageLock的view了
首先我们的ImageLock 要继承自View 然后重写onlayout 方法,在onlayout方法中进行布局。将9个点的分布处理好
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); height=getHeight(); width=getWidth(); pointList.clear(); //进行点的布局 for(int i=0;i<3;i++){ for (int j=0;j<3;j++){ Point point=new Point((2*j+1)*width/6,(2*i+1)*width/6,i*3+j); pointList.add(point); } } }
然后就是画点划线了,在这里我们定义一个划线的方法,然后监视手指触摸的那个点跟九个点的距离,这个距离在小于预先设定的一个值的时候就判定那个点被选中
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画一般的点 for(int i=0;i<pointList.size();i++){ Point point=pointList.get(i); point.draw(canvas); } //划线 if(pointQueue.size()>0){ drawTouchedLine(canvas); } }
public void drawTouchedLine(Canvas canvas){ //设置画笔的粗细 linePaint.setStrokeWidth(painWidth); //设置画笔的颜色 if(isMatch){ linePaint.setColor(matchColor); }else{ linePaint.setColor(errorColor); } //设置画笔的透明度 linePaint.setAlpha(100); for(int j=0;j<pointQueue.size()-1;j++){ Point point1=pointQueue.get(j); Point point2=pointQueue.get(j+1); canvas.drawLine(point1.getX(),point1.getY(),point2.getX(),point2.getY(),linePaint); } //最后一条能动的线 if(isMatch&&isTouched){ Point latePoint=pointQueue.get(pointQueue.size()-1); canvas.drawLine(latePoint.getX(),latePoint.getY(),eventPoint.getX(),eventPoint.getY(),linePaint); }else{ return ; } }
最后将视图的手势抬起设置一个接口
private OnTouchUpListener listener; public interface OnTouchUpListener{ public void onTouchUp(); }
public void setTouchUpListener(OnTouchUpListener listener){ this.listener=listener; }
这里将所有的代码贴出来吧,不难,也没有什么写的
public class ImageLock extends View { //视图的整体宽高 private int height; private int width; /** * 存放所有点的集合 */ private List<Point> pointList=new ArrayList<Point>(); /** *被选择点的顺序队列 */ private List<Point> pointQueue=new ArrayList<Point>(); /** * 是否是对的 */ private boolean isMatch; /** * 事件的点 */ private Point eventPoint; /** * 圆的半径 */ private int radious; /** * 画线的画笔 */ private Paint linePaint; /** * 划线的颜色 */ private int matchColor; private int errorColor; /** * 划线的粗细 */ private int painWidth; /** * 是否抬起来 */ private boolean isTouched; private OnTouchUpListener listener; public interface OnTouchUpListener{ public void onTouchUp(); } public ImageLock(Context context) { super(context); init(); } public ImageLock(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ImageLock(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void init(){ isMatch=true; radious=50; linePaint=new Paint(); eventPoint=new Point(); matchColor=Color.CYAN; errorColor=Color.RED; painWidth=20; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); height=getHeight(); width=getWidth(); pointList.clear(); //进行点的布局 for(int i=0;i<3;i++){ for (int j=0;j<3;j++){ Point point=new Point((2*j+1)*width/6,(2*i+1)*width/6,i*3+j); pointList.add(point); } } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画一般的点 for(int i=0;i<pointList.size();i++){ Point point=pointList.get(i); point.draw(canvas); } //划线 if(pointQueue.size()>0){ drawTouchedLine(canvas); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: eventPoint.setLocation(event.getX(), event.getY()); isTouched=true; //判断是不是触碰到点 pointTouchEvent(eventPoint); break; case MotionEvent.ACTION_UP: isTouched=false; if(listener!=null){ listener.onTouchUp(); } invalidate(); break; } return true; } public void drawTouchedLine(Canvas canvas){ //设置画笔的粗细 linePaint.setStrokeWidth(painWidth); //设置画笔的颜色 if(isMatch){ linePaint.setColor(matchColor); }else{ linePaint.setColor(errorColor); } //设置画笔的透明度 linePaint.setAlpha(100); for(int j=0;j<pointQueue.size()-1;j++){ Point point1=pointQueue.get(j); Point point2=pointQueue.get(j+1); canvas.drawLine(point1.getX(),point1.getY(),point2.getX(),point2.getY(),linePaint); } //最后一条能动的线 if(isMatch&&isTouched){ Point latePoint=pointQueue.get(pointQueue.size()-1); canvas.drawLine(latePoint.getX(),latePoint.getY(),eventPoint.getX(),eventPoint.getY(),linePaint); }else{ return ; } } public void pointTouchEvent(Point point){ for(int i=0;i<pointList.size();i++){ Point currenPoint=pointList.get(i); //判断是否触碰到点 if(Math.sqrt(Math.pow(point.getX()-currenPoint.getX(),2)+Math.pow(point.getY()-currenPoint.getY(),2))<=radious){ //给触碰到的点进行压栈 for(int j=0;j<pointQueue.size();j++){ if(pointQueue.get(j).getId()==currenPoint.getId()){ return;//如果这个点已经在这个队列中就不让他可以压栈,从而进行事件的消费 } } pointList.get(i).setTouched(true); currenPoint.setTouched(true); pointQueue.add(currenPoint); } } invalidate(); } public void setMatch(boolean isMatch){ this.isMatch=isMatch; for(int i=0;i<pointQueue.size();i++){ pointQueue.get(i).setIsError(!isMatch); } invalidate(); } public void resetChooseList(){ pointQueue.clear(); for(int i=0;i<pointList.size();i++){ pointList.get(i).setTouched(false); pointList.get(i).setIsError(false); } isMatch=true; invalidate(); } public String getSecret(){ String secret=new String(); for(int i=0;i<pointQueue.size();i++){ secret+=pointQueue.get(i).getId(); } return secret; } public void setTouchUpListener(OnTouchUpListener listener){ this.listener=listener; } public void setErrorColor(int errorColor) { this.errorColor = errorColor; } public void setLinePaint(Paint linePaint) { this.linePaint = linePaint; } public void setMatchColor(int matchColor) { this.matchColor = matchColor; } public void setPainWidth(int painWidth) { this.painWidth = painWidth; } public void setRadious(int radious) { this.radious = radious; } public void setWidth(int width) { this.width = width; } public void setHeight(int height) { this.height = height; }}
最后在主函数中调用
具体怎么设置视图都有接口,还可以对数据进行一些加密保存在本地,具体也就不在阐述了,一下是我测试的时候的代码以及布局文件
public class MainActivity extends AppCompatActivity { private ImageLock imageLock; private Button btn; String str; private String key="123"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageLock= (ImageLock) findViewById(R.id.iamgeLock_main); btn= (Button) findViewById(R.id.btn_main_clear); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imageLock.resetChooseList(); } }); imageLock.setTouchUpListener(new ImageLock.OnTouchUpListener() { @Override public void onTouchUp() { imageLock.setMatch(false); str = imageLock.getSecret(); if(str.equals(key)){ Toast.makeText(MainActivity.this,"right",Toast.LENGTH_SHORT).show(); imageLock.setMatch(true); }else{ imageLock.setMatch(false); } } }); }}
布局文件
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".activity.MainActivity"> <com.happysmile.imagelock.custom.ImageLock android:layout_marginBottom="150dp" android:id="@+id/iamgeLock_main" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RelativeLayout android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="150dp"> <Button android:background="@color/colorPrimary" android:textSize="50dp" android:gravity="center" android:layout_alignParentBottom="true" android:text="clear" android:id="@+id/btn_main_clear" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
最后:本人写博客经验不足,水平有限,还望大家多指正,共同学习
0 0
- Android 实现图形解锁
- 手势密码 图形解锁 实现
- Android图形解锁的绘制
- Android:图形解锁的绘制
- Android实现手势解锁
- android 图形锁锁死之后 解锁【备忘】
- android 手势解锁的实现
- 图形解锁的代码实现(付源码)
- android解决图形解锁图案忘记的方法
- JS 手势图形解锁
- 自用图形解锁分析
- android 图形底层实现
- Android之九宫格解锁的实现
- Android Jelly Bean滑动解锁控件实现
- Android自动化解锁脚本实现解析
- Android之九宫格解锁的实现
- Android纯代码实现九宫格解锁
- Android之九宫格解锁的实现
- struts2的action包含多个方法调用方式
- MFC 程序嵌入python 的调试
- linux命令man、info、pinfo
- Java软件工程师的基础知识点
- MD5加密工具类
- Android 实现图形解锁
- 格式化数字的方法
- 关于这次WEB项目开发的一点经验
- 面试相关
- 顺序存储结构与链式存储结构的比较(也可以说的顺序表与链表的比较)
- FOJ 2213 Common Tangents 【第六届福建省大学生程序设计竞赛】
- 家谱树
- HTML中Select的使用详解
- 面向对象思维导图