zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

android九宫格滑动解锁开机实例源码学习

Android实例源码学习 解锁 开机 滑动 九宫格
2023-06-13 09:14:44 时间
效果图由于网站占时不能上传,以后补上。
NinePointLineView.java
复制代码代码如下:

packageorg.demo.custon_view;
importorg.demo.utils.MLog;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.Paint.Cap;
importandroid.graphics.Typeface;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.View;
publicclassNinePointLineViewextendsView{
PaintlinePaint=newPaint();
PaintwhiteLinePaint=newPaint();
PainttextPaint=newPaint();
//由于两个图片都是正方形,所以获取一个长度就行了
BitmapdefaultBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.lock);
intdefaultBitmapRadius=defaultBitmap.getWidth()/2;
//初始化被选中图片的直径、半径
BitmapselectedBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area);
intselectedBitmapDiameter=selectedBitmap.getWidth();
intselectedBitmapRadius=selectedBitmapDiameter/2;
//定义好9个点的数组
PointInfo[]points=newPointInfo[9];
//相应ACTION_DOWN的那个点
PointInfostartPoint=null;
//屏幕的宽高
intwidth,height;
//当ACTION_MOVE时获取的X,Y坐标
intmoveX,moveY;
//是否发生ACTION_UP
booleanisUp=false;
//最终生成的用户锁序列
StringBufferlockString=newStringBuffer();
publicNinePointLineView(Contextcontext){
super(context);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
publicNinePointLineView(Contextcontext,AttributeSetattrs){
super(context,attrs);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
MLog.i("onMeasure");
//初始化屏幕大小
width=getWidth();
height=getHeight();
if(width!=0&&height!=0){
initPoints(points);
}
MLog.i("width、height="+width+"、"+height);
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
@Override
protectedvoidonLayout(booleanchanged,intleft,inttop,intright,
intbottom){
MLog.i("onLayout");
super.onLayout(changed,left,top,right,bottom);
}
privateintstartX=0,startY=0;
@Override
protectedvoidonDraw(Canvascanvas){
canvas.drawText("用户的滑动顺序:"+lockString,0,40,textPaint);
if(moveX!=0&&moveY!=0&&startX!=0&&startY!=0){
//绘制当前活动的线段
drawLine(canvas,startX,startY,moveX,moveY);
}
drawNinePoint(canvas);
super.onDraw(canvas);
}
//记住,这个DOWN和MOVE、UP是成对的,如果没从UP释放,就不会再获得DOWN;
//而获得DOWN时,一定要确认消费该事件,否则MOVE和UP不会被这个View的onTouchEvent接收
@Override
publicbooleanonTouchEvent(MotionEventevent){
booleanflag=true;
if(isUp){//如果已滑完,重置每个点的属性和lockString
finishDraw();
//当UP后,要返回false,把事件释放给系统,否则无法获得Down事件
flag=false;
}else{//没滑完,则继续绘制
handlingEvent(event);
//这里要返回true,代表该View消耗此事件,否则不会收到MOVE和UP事件
flag=true;
}
returnflag;
}
privatevoidhandlingEvent(MotionEventevent){
switch(event.getAction()){
caseMotionEvent.ACTION_MOVE:
moveX=(int)event.getX();
moveY=(int)event.getY();
MLog.i("onMove:"+moveX+"、"+moveY);
for(PointInfotemp:points){
if(temp.isInMyPlace(moveX,moveY)&&temp.isNotSelected()){
temp.setSelected(true);
startX=temp.getCenterX();
startY=temp.getCenterY();
intlen=lockString.length();
if(len!=0){
intpreId=lockString.charAt(len-1)-48;
points[preId].setNextId(temp.getId());
}
lockString.append(temp.getId());
break;
}
}
invalidate(0,height-width,width,height);
break;
caseMotionEvent.ACTION_DOWN:
intdownX=(int)event.getX();
intdownY=(int)event.getY();
MLog.i("onDown:"+downX+"、"+downY);
for(PointInfotemp:points){
if(temp.isInMyPlace(downX,downY)){
temp.setSelected(true);
startPoint=temp;
startX=temp.getCenterX();
startY=temp.getCenterY();
lockString.append(temp.getId());
break;
}
}
invalidate(0,height-width,width,height);
break;
caseMotionEvent.ACTION_UP:
MLog.i("onUp");
startX=startY=moveX=moveY=0;
isUp=true;
invalidate();
break;
default:
MLog.i("收到其他事件!!");
break;
}
}
privatevoidfinishDraw(){
for(PointInfotemp:points){
temp.setSelected(false);
temp.setNextId(temp.getId());
}
lockString.delete(0,lockString.length());
isUp=false;
invalidate();
}
privatevoidinitPoints(PointInfo[]points){
intlen=points.length;
intseletedSpacing=(width-selectedBitmapDiameter*3)/4;
//被选择时显示图片的左上角坐标
intseletedX=seletedSpacing;
intseletedY=height-width+seletedSpacing;
//没被选时图片的左上角坐标
intdefaultX=seletedX+selectedBitmapRadius-defaultBitmapRadius;
intdefaultY=seletedY+selectedBitmapRadius-defaultBitmapRadius;
//绘制好每个点
for(inti=0;i<len;i++){
if(i==3||i==6){
seletedX=seletedSpacing;
seletedY+=selectedBitmapDiameter+seletedSpacing;
defaultX=seletedX+selectedBitmapRadius
-defaultBitmapRadius;
defaultY+=selectedBitmapDiameter+seletedSpacing;
}
points[i]=newPointInfo(i,defaultX,defaultY,seletedX,seletedY);
seletedX+=selectedBitmapDiameter+seletedSpacing;
defaultX+=selectedBitmapDiameter+seletedSpacing;
}
}
privatevoidinitPaint(){
initLinePaint(linePaint);
initTextPaint(textPaint);
initWhiteLinePaint(whiteLinePaint);
}
/**
*初始化文本画笔
*@parampaint
*/
privatevoidinitTextPaint(Paintpaint){
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
textPaint.setTypeface(Typeface.MONOSPACE);
}
/**
*初始化黑线画笔
*
*@parampaint
*/
privatevoidinitLinePaint(Paintpaint){
paint.setColor(Color.GRAY);
paint.setStrokeWidth(defaultBitmap.getWidth());
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
*初始化白线画笔
*
*@parampaint
*/
privatevoidinitWhiteLinePaint(Paintpaint){
paint.setColor(Color.WHITE);
paint.setStrokeWidth(defaultBitmap.getWidth()-5);
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
*绘制已完成的部分
*
*@paramcanvas
*/
privatevoiddrawNinePoint(Canvascanvas){
if(startPoint!=null){
drawEachLine(canvas,startPoint);
}
//绘制每个点的图片
for(PointInfopointInfo:points){
if(pointInfo.isSelected()){//绘制大圈
canvas.drawBitmap(selectedBitmap,pointInfo.getSeletedX(),
pointInfo.getSeletedY(),null);
}
//绘制点
canvas.drawBitmap(defaultBitmap,pointInfo.getDefaultX(),
pointInfo.getDefaultY(),null);
}
}
/**
*递归绘制每两个点之间的线段
*
*@paramcanvas
*@parampoint
*/
privatevoiddrawEachLine(Canvascanvas,PointInfopoint){
if(point.hasNextId()){
intn=point.getNextId();
drawLine(canvas,point.getCenterX(),point.getCenterY(),
points[n].getCenterX(),points[n].getCenterY());
//递归
drawEachLine(canvas,points[n]);
}
}
/**
*先绘制黑线,再在上面绘制白线,达到黑边白线的效果
*
*@paramcanvas
*@paramstartX
*@paramstartY
*@paramstopX
*@paramstopY
*/
privatevoiddrawLine(Canvascanvas,floatstartX,floatstartY,
floatstopX,floatstopY){
canvas.drawLine(startX,startY,stopX,stopY,linePaint);
canvas.drawLine(startX,startY,stopX,stopY,whiteLinePaint);
}
/**
*用来表示一个点
*
*@authorzkwlx
*
*/
privateclassPointInfo{
//一个点的ID
privateintid;
//当前点所指向的下一个点的ID,当没有时为自己ID
privateintnextId;
//是否被选中
privatebooleanselected;
//默认时图片的左上角X坐标
privateintdefaultX;
//默认时图片的左上角Y坐标
privateintdefaultY;
//被选中时图片的左上角X坐标
privateintseletedX;
//被选中时图片的左上角Y坐标
privateintseletedY;
publicPointInfo(intid,intdefaultX,intdefaultY,intseletedX,
intseletedY){
this.id=id;
this.nextId=id;
this.defaultX=defaultX;
this.defaultY=defaultY;
this.seletedX=seletedX;
this.seletedY=seletedY;
}
publicbooleanisSelected(){
returnselected;
}
publicbooleanisNotSelected(){
return!isSelected();
}
publicvoidsetSelected(booleanselected){
this.selected=selected;
}
publicintgetId(){
returnid;
}
publicintgetDefaultX(){
returndefaultX;
}
publicintgetDefaultY(){
returndefaultY;
}
publicintgetSeletedX(){
returnseletedX;
}
publicintgetSeletedY(){
returnseletedY;
}
publicintgetCenterX(){
returnseletedX+selectedBitmapRadius;
}
publicintgetCenterY(){
returnseletedY+selectedBitmapRadius;
}
publicbooleanhasNextId(){
returnnextId!=id;
}
publicintgetNextId(){
returnnextId;
}
publicvoidsetNextId(intnextId){
this.nextId=nextId;
}
/**
*坐标(x,y)是否在当前点的范围内
*
*@paramx
*@paramy
*@return
*/
publicbooleanisInMyPlace(intx,inty){
booleaninX=x>seletedX
&&x<(seletedX+selectedBitmapDiameter);
booleaninY=y>seletedY
&&y<(seletedY+selectedBitmapDiameter);
return(inX&&inY);
}
}
}

NinePointView.java
复制代码代码如下:

packageorg.demo.custon_view;
importorg.demo.utils.MLog;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Matrix;
importandroid.graphics.Paint;
importandroid.graphics.Paint.Cap;
importandroid.graphics.Path;
importandroid.graphics.Typeface;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.View;
publicclassNinePointViewextendsView{
PaintlinePaint=newPaint();
PainttextPaint=newPaint();
Pathpath=newPath();
//由于两个图片都是正方形,所以获取一个长度就行了
BitmapdefaultBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.lock);
intdefaultBitmapRadius=defaultBitmap.getWidth()/2;
//初始化被选中图片的直径、半径
BitmapselectedBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area);
intselectedBitmapDiameter=selectedBitmap.getWidth();
intselectedBitmapRadius=selectedBitmapDiameter/2;
//初始化指示器的图片
BitmapindicateBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area_next);
BitmaptempBitmap=null;
//定义好9个点的数组
PointInfo[]points=newPointInfo[9];
//屏幕的宽高
intwidth,height;
//当ACTION_MOVE时获取的X,Y坐标
intmoveX,moveY;
//是否发生ACTION_UP
booleanisUp=false;
//最终生成的用户锁序列
StringBufferlockString=newStringBuffer();
Matrixmatrix=newMatrix();
publicNinePointView(Contextcontext){
super(context);
this.setBackgroundColor(Color.WHITE);
initLinePaint(linePaint);
initTextPaint(textPaint);
}
publicNinePointView(Contextcontext,AttributeSetattrs){
super(context,attrs);
this.setBackgroundColor(Color.WHITE);
initLinePaint(linePaint);
initTextPaint(textPaint);
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
MLog.i("onMeasure");
width=getWidth();
height=getHeight();
if(width!=0&&height!=0){
initPoints(points);
}
MLog.i("width、height="+width+"、"+height);
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
@Override
protectedvoidonLayout(booleanchanged,intleft,inttop,intright,
intbottom){
MLog.i("onLayout");
super.onLayout(changed,left,top,right,bottom);
}
privateintstartX=0,startY=0;
@Override
protectedvoidonDraw(Canvascanvas){
canvas.drawText("用户的滑动顺序:"+lockString,0,40,textPaint);
if(moveX!=0&&moveY!=0&&startX!=0&&startY!=0){
//绘制当前活动的线段
canvas.drawLine(startX,startY,moveX,moveY,linePaint);
}
drawNinePoint(canvas,linePaint);
super.onDraw(canvas);
}
//记住,这个DOWN和MOVE、UP是成对的,如果没从UP释放,就不会再获得DOWN;
//而获得DOWN时,一定要确认消费该事件,否则MOVE和UP不会被这个VIEW的onTouchEvent接收
@Override
publicbooleanonTouchEvent(MotionEventevent){
booleanflag=true;
if(isUp){//如果已滑完,则把整个Canvas重置
finishDraw();
//当UP后,要返回false,把事件释放给系统,否则无法获得Down事件
flag=false;
}else{//没滑完,则继续绘制
handlingEvent(event);
//这里要返回true,否则代表该View不消耗此事件,交给系统处理,则不会再收到MOVE和UP事件
flag=true;
}
returnflag;
}
privatevoidhandlingEvent(MotionEventevent){
switch(event.getAction()){
caseMotionEvent.ACTION_MOVE:
moveX=(int)event.getX();
moveY=(int)event.getY();
MLog.i("onMove:"+moveX+"、"+moveY);
for(PointInfotemp:points){
if(temp.isInMyPlace(moveX,moveY)&&temp.isNotSelected()){
temp.setSelected(true);
startX=temp.getCenterX();
startY=temp.getCenterY();
intlen=lockString.length();
if(len!=0){
intpreId=lockString.charAt(len-1)-48;
points[preId].setNextId(temp.getId());
}
lockString.append(temp.getId());
break;
}
}
invalidate(0,height-width,width,height);
break;
caseMotionEvent.ACTION_DOWN:
intdownX=(int)event.getX();
intdownY=(int)event.getY();
MLog.i("onDown:"+downX+"、"+downY);
for(PointInfotemp:points){
if(temp.isInMyPlace(downX,downY)){
temp.setSelected(true);
startX=temp.getCenterX();
startY=temp.getCenterY();
lockString.append(temp.getId());
break;
}
}
invalidate(0,height-width,width,height);
break;
caseMotionEvent.ACTION_UP:
MLog.i("onUp");
startX=startY=moveX=moveY=0;
isUp=true;
invalidate();
break;
default:
MLog.i("收到其他事件!!");
break;
}
}
privatevoidfinishDraw(){
for(PointInfotemp:points){
temp.setSelected(false);
temp.setNextId(temp.getId());
}
lockString.delete(0,lockString.length());
isUp=false;
invalidate();
}
privatevoidinitPoints(PointInfo[]points){
intlen=points.length;
intseletedSpacing=(width-selectedBitmapDiameter*3)/4;
//被选择时显示图片的左上角坐标
intseletedX=seletedSpacing;
intseletedY=height-width+seletedSpacing;
//没被选时图片的左上角坐标
intdefaultX=seletedX+selectedBitmapRadius-defaultBitmapRadius;
intdefaultY=seletedY+selectedBitmapRadius-defaultBitmapRadius;
for(inti=0;i<len;i++){
if(i==3||i==6){
seletedX=seletedSpacing;
seletedY+=selectedBitmapDiameter+seletedSpacing;
defaultX=seletedX+selectedBitmapRadius
-defaultBitmapRadius;
defaultY+=selectedBitmapDiameter+seletedSpacing;
}
points[i]=newPointInfo(i,defaultX,defaultY,seletedX,seletedY);
seletedX+=selectedBitmapDiameter+seletedSpacing;
defaultX+=selectedBitmapDiameter+seletedSpacing;
}
}
privatevoidinitTextPaint(Paintpaint){
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
textPaint.setTypeface(Typeface.MONOSPACE);
}
/**
*初始化线画笔
*
*@parampaint
*/
privatevoidinitLinePaint(Paintpaint){
paint.setColor(Color.GRAY);
paint.setStrokeWidth(defaultBitmap.getWidth());
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
*绘制已完成的部分
*
*@paramcanvas
*/
privatevoiddrawNinePoint(Canvascanvas,Paintpaint){
//先把用户画出的线绘制好
for(PointInfopointInfo:points){
if(pointInfo.hasNextId()){
intn=pointInfo.getNextId();
canvas.drawLine(pointInfo.getCenterX(),pointInfo.getCenterY(),
points[n].getCenterX(),points[n].getCenterY(),paint);
}
}
//绘制每个点的图片
for(PointInfopointInfo:points){
if(pointInfo.isSelected()){
if(pointInfo.hasNextId()){
matrix.reset();
inti=(int)Math.abs(Math.random()*1000-640);
MLog.i("随机到的角度:"+i);
matrix.setRotate(i);
tempBitmap=Bitmap.createBitmap(indicateBitmap,0,0,
indicateBitmap.getWidth(),
indicateBitmap.getHeight(),matrix,false);
canvas.drawBitmap(tempBitmap,pointInfo.getSeletedX(),
pointInfo.getSeletedY(),paint);
}else{
canvas.drawBitmap(selectedBitmap,pointInfo.getSeletedX(),
pointInfo.getSeletedY(),paint);
}
}
canvas.drawBitmap(defaultBitmap,pointInfo.getDefaultX(),
pointInfo.getDefaultY(),paint);
}
}
privateclassPointInfo{
//一个点的ID
privateintid;
//当前点所指向的下一个点的ID,当没有时为自己ID
privateintnextId;
//是否被选中
privatebooleanselected;
//默认时图片的左上角X坐标
privateintdefaultX;
//默认时图片的左上角Y坐标
privateintdefaultY;
//被选中时图片的左上角X坐标
privateintseletedX;
//被选中时图片的左上角Y坐标
privateintseletedY;
publicPointInfo(intid,intdefaultX,intdefaultY,intseletedX,
intseletedY){
this.id=id;
this.nextId=id;
this.defaultX=defaultX;
this.defaultY=defaultY;
this.seletedX=seletedX;
this.seletedY=seletedY;
}
publicbooleanisSelected(){
returnselected;
}
publicbooleanisNotSelected(){
return!isSelected();
}
publicvoidsetSelected(booleanselected){
this.selected=selected;
}
publicintgetId(){
returnid;
}
publicintgetDefaultX(){
returndefaultX;
}
publicintgetDefaultY(){
returndefaultY;
}
publicintgetSeletedX(){
returnseletedX;
}
publicintgetSeletedY(){
returnseletedY;
}
publicintgetCenterX(){
returnseletedX+selectedBitmapRadius;
}
publicintgetCenterY(){
returnseletedY+selectedBitmapRadius;
}
publicbooleanhasNextId(){
returnnextId!=id;
}
publicintgetNextId(){
returnnextId;
}
publicvoidsetNextId(intnextId){
this.nextId=nextId;
}
/**
*坐标(x,y)是否在当前点的范围内
*
*@paramx
*@paramy
*@return
*/
publicbooleanisInMyPlace(intx,inty){
booleaninX=x>seletedX
&&x<(seletedX+selectedBitmapDiameter);
booleaninY=y>seletedY
&&y<(seletedY+selectedBitmapDiameter);
if(inX&&inY){
returntrue;
}else{
returnfalse;
}
}
}
}