Android 自定义九宫格手势锁
程序员文章站
2022-06-29 12:00:40
预览效果图如下:
主要的方法是重写view.ontouchevent( motionevent event ) , 常用的三个操作:action_down...
预览效果图如下:
主要的方法是重写view.ontouchevent( motionevent event ) , 常用的三个操作:action_down 手指触摸屏幕 ; action_up 手指离开屏幕;
action_move手指在屏幕滑动。
如果该方法返回true ,表示该事件已经被view处理,不再向上层的view或activity传递 ; 如果返回false, 表示事件未处理,继续传递。
具体代码如下:
package com.ninegrid; import android.content.context; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.util.attributeset; import android.view.motionevent; import android.view.view; /** * created by administrator on 2017/6/24. */ public class suduview extends view { //定义默认常量 private static final int default_cell_width = 200 ; private static final int default_cell_stroke_width = 10 ; private static final int default_space = 100 ; //九宫格数组 private cell mcells[] = new cell[9] ; //直径 private int mcellwidth; //半径 private int mcellradius; //边框宽度 private int mcellstrokewidth; //空白部分 private int mspace ; //定义画笔 private paint mpaintnormal ; private paint mpaintselected ; private float mcurrentx ; private float mcurrenty ; //判断是否结束的标识 private boolean mfinish = false ; private stringbuffer msbselected = new stringbuffer(20); public suduview(context context) { super(context); init(); } public suduview(context context, attributeset attrs) { super(context, attrs); init(); } public suduview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(); } private void init(){ //初始化画笔 mcellwidth = default_cell_width ; mcellradius = default_cell_width >> 1 ; mcellstrokewidth = default_cell_stroke_width ; mspace = default_space ; mpaintnormal = new paint(); mpaintnormal.setcolor(color.white); mpaintnormal.setstrokewidth(mcellstrokewidth); mpaintnormal.setstyle(paint.style.stroke); mpaintnormal.setantialias(true); mpaintselected = new paint(); mpaintselected.setcolor(color.cyan); mpaintselected.setstrokewidth(mcellstrokewidth); mpaintselected.setstyle(paint.style.stroke); mpaintselected.setantialias(true); cell cell ; float x; float y; //计算每个格子的坐标 for( int i = 0 ; i < 9 ; i ++ ){ x = mspace * ( i%3 + 1 ) + mcellradius + mcellwidth * ( i%3 ) ; y = mspace * ( i/3 + 1 ) + mcellradius + mcellwidth * ( i/3 ) ; cell = new cell(x , y); mcells[i] = cell ; } } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); drawcell(canvas); drawline(canvas); } //绘制连接线 private void drawline( canvas canvas ){ if("".equals(msbselected.tostring())){ return; } string[] selectedindexs = msbselected.tostring().split(","); cell cell = mcells[integer.valueof(selectedindexs[0])]; cell nextcell ; //绘制每两个格子中心点之间的连接线 if( selectedindexs.length > 1) { for (int i = 1; i < selectedindexs.length; i++) { nextcell = mcells[integer.valueof(selectedindexs[i])]; canvas.drawline(cell.getcenterx(), cell.getcentery(), nextcell.getcenterx(), nextcell.getcentery(), mpaintselected); cell = nextcell; } } //绘制格子到其他空白位置的连接线 if( !mfinish ) { canvas.drawline(cell.getcenterx(), cell.getcentery(), mcurrentx, mcurrenty, mpaintselected); } } private void drawcell( canvas canvas ){ for ( int i = 0 ; i < 9 ; i ++ ){ canvas.drawcircle(mcells[i].getcenterx(), mcells[i].getcentery() , mcellradius , mcells[i].isselected() ? mpaintselected : mpaintnormal ); } } //处理点击事件 @override public boolean ontouchevent(motionevent event) { switch ( event.getaction()){ case motionevent.action_down: //如果手指已经松开,则所有格子变为初始状态 if( mfinish ){ for ( int i = 0 ; i < 9 ; i ++ ){ mcells[i].setselected(false); } mfinish = false ; msbselected.delete(0,msbselected.length()); invalidate(); return false; } handledownevent(event); break; //松开则结束 case motionevent.action_up: mfinish = true ; break; case motionevent.action_move: handlemoveevent(event); break; } //表示已处理,不向上传递 return true ; } //处理手指移动的事件 private void handlemoveevent( motionevent event ){ int index = findcellindex(event.getx(),event.gety()); if( index != -1 ){ mcells[index].setselected(true); msbselected.append(index).append(","); } invalidate(); mcurrentx = event.getx(); mcurrenty = event.gety(); } //处理手指按下的事件 private void handledownevent( motionevent event){ int index = findcellindex(event.getx(),event.gety()); if( index != -1 ){ mcells[index].setselected(true); msbselected.append(index).append(","); invalidate(); } mcurrentx = event.getx(); mcurrenty = event.gety(); } //根据坐标判断点击的哪个格子 private int findcellindex( float x , float y){ float cellx ; float celly ; int result = -1 ; for( int i = 0 ; i < 9 ; i ++ ){ if( mcells[i].isselected()){ continue; } //获取每个格子的坐标 cellx = mcells[i].getcenterx(); celly = mcells[i].getcentery(); //计算按下的点到每个格子的距离 float tempx = cellx - x ; float tempy = celly - y ; float distance = (float) math.sqrt(tempx * tempx + tempy * tempy); //如果点击的位置在某个格子的圆内 if( distance < mcellradius ){ result = i ; break; } } //返回该格子的位置 return result ; } }
最后在布局文件中引用该view即可,若想实现更高的定制性,可以仿照上一篇文章重写view的onmearsure方法并增加自定义属性。
以上所述是小编给大家介绍的android 自定义九宫格手势锁,希望对大家有所帮助