android -- 做个记录,以后方便回顾
来源:互联网 发布:人工智能主题的基金 编辑:程序博客网 时间:2024/04/27 21:26
--------------------------------效果图。
大致思路:先画出9个圆环,根据手势(down,move,up)重新绘制canvas。比如down的时候设置cell的bitmap为另一张红色圈的图片,move的时候画出一条从currentCell到手指停住的坐标点的直线。up的时候获取手势结果。
注意:①9个环id编号的形式为(1,2,3 当手指down在1号位置,然后move到3号位置时,需要连接1-2,2-3,而不是直接连接1-3。
4,5,6
7,8,9)
②辅助线的意思是指,手指移到其他空白区域是的一条辅助线,因为只有手指触摸到圆环内部范围,才能真正的连上一条直线,所以手指触摸在其他非圆环位置的画,画条辅助线,并不保存这条线。
注释应该很详细了
public class LockPattern extends View{
private Cell cell[] = new Cell[9];
private Cell currentCell;
private Paint mPaint; //定义画笔
private int path[][]; //线
private int pathCount;//线的数量
private float mPathx,mPathy;//辅助线,不保存的线。
private int width;
private int height;
private float screenWidth; //手机屏幕宽度 和 高度
private float screenHeight;
private Bitmap bStart; //不按 显示一个环
private Bitmap bEnd; //按住 显示一个圈
private int bRadius; //环半径
class Cell{
int id; //9个环的编号
Bitmap bitmap; //当前图片
int touched; //触摸编号(单位递增)
float x;//显示位置
float y;
}
public LockPattern(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
mPaint = new Paint();
resetPath(); //初始化边
WindowManager wm = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);
screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
bStart = BitmapFactory.decodeResource(this.getResources()
, R.drawable.circle_red_start);
bEnd = BitmapFactory.decodeResource(this.getResources()
, R.drawable.circle_red_end);
Log.d("屏幕的宽度和高度", "("+screenWidth+","+screenHeight+")");
initCell(); //初始化9个环
}
public void initCell(){
float bitmapWidth = bStart.getWidth(); //图片宽度
bRadius = (int)(bitmapWidth/2);
float distance = (screenWidth - 3*bitmapWidth)/4; //手势锁 间距
float H = (screenHeight-distance*2-bitmapWidth*3)/2; //锁的上半部分空白高度
for(int i=0;i<3;i++){
for(int k=0;k<3;k++){
int index = i*3+k;
cell[index] = new Cell();
cell[index].id = i*3+k+1;
cell[index].bitmap = bStart;
cell[index].x = distance*(k+1)+bitmapWidth*k;
cell[index].y = H+distance*i+bitmapWidth*i;
cell[index].touched = 0;
}
}
//cell[0].drawable_first = new Drawable();
}
@Override
public void layout(int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.layout(l, t, r, b);
}
@Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
super.draw(canvas);
/*mPaint.setColor(Color.GREEN);
mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawRect(50, 50, 150, 150, mPaint);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Style.STROKE);
mPaint.setTextSize(30.0f);
canvas.drawText("computer", 100, 100, mPaint);
mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawCircle(200, 200, 50, mPaint);*/
//画环
for(int i=0;i<9;i++){
canvas.drawBitmap(cell[i].bitmap, cell[i].x, cell[i].y, null);
if(cell[i].touched != 0){
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.FILL);
}else{
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.STROKE);
}
canvas.drawCircle(cell[i].x+bRadius, cell[i].y+bRadius, 10, mPaint);
}
//画线
for(int i=0;i<9;i++){
for(int k=0;k<9;k++){
//Log.d("path["+i+"]["+k+"]",path[i][k]+","+path[k][i]);
if(path[i][k] != 0 && path[k][i] != 0){
mPaint.setStyle(Style.FILL);
mPaint.setStrokeWidth(16);
mPaint.setColor(Color.WHITE);
mPaint.setAlpha(50);
canvas.drawLine(cell[i].x+bRadius, cell[i].y+bRadius
, cell[k].x+bRadius, cell[k].y+bRadius, mPaint);
}
}
}
//画辅助线
if(mPathx!=0 && mPathy!=0){
mPaint.setStyle(Style.FILL);
mPaint.setStrokeWidth(16);
mPaint.setColor(Color.WHITE);
canvas.drawLine(currentCell.x+bRadius, currentCell.y+bRadius
, mPathx, mPathy, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float x = event.getX();
float y = event.getY();
int pCellId = getTouchDownCircle(x, y);
if(event.getAction() == MotionEvent.ACTION_DOWN){
Log.d("MotinEvent","DOWN");
if(pCellId == 0){
return false;
}else{
resetCells();
resetPath();
Log.d("press cell id", ""+pCellId);
cell[pCellId-1].bitmap = bEnd;
cell[pCellId-1].touched = 1;
currentCell = cell[pCellId-1];
}
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
//Log.d("MotinEvent", "MOVE");
if(pCellId == 0){
//移动的位置不在下一个环上,所以只画辅助线,不保存
mPathx = x;
mPathy = y;
}else{
//Log.d("move to cell", ""+pCellId);
//Log.d("");
if(cell[pCellId-1].touched == 0){ //判断环是否被点击过
mPathx = 0;
mPathy = 0;
addLines(pCellId); //添加线
currentCell = cell[pCellId-1];
//Log.d("currentCell",currentCell.id+"");
}else{
mPathx = x;
mPathy = y;
}
}
}else if(event.getAction() == MotionEvent.ACTION_UP){
Log.d("MotinEvent","UP");
mPathx = 0;
mPathy = 0;
int res[] = this.getLockPatternResult();
String sRes="";
for(int i=0;i<9;i++)
sRes = sRes+res[i];
Log.d("result",sRes);
}
super.invalidate();
return true;
}
/**
* 重置所有cell
*/
private void resetCells(){
for(int i=0;i<9;i++){
cell[i].bitmap = bStart;
cell[i].touched = 0;
}
}
/**
* 重置path
*/
private void resetPath(){
pathCount = 0;
path = new int[9][9];
for(int i=0;i<9;i++){
for(int k=0;k<9;k++)
path[i][k]=path[k][i] = 0;
}
mPathx = 0;
mPathy = 0;
}
/**
* 判断点击位置点击中哪个环
*/
private int getTouchDownCircle(float x, float y){
for(int i=0;i<9;i++){
//计算两点间的距离
double dis = Math.sqrt((x-cell[i].x-bRadius)*(x-cell[i].x-bRadius)
+ (y-cell[i].y-bRadius)*(y-cell[i].y-bRadius));
if((dis-bRadius)<0){
return cell[i].id;
}
}
return 0;
}
/**
* 添加线(如果1环和3环连接 由于2环处于1,3环之间 则先连接1-2再连接 2-3)
*/
private void addLines(int nextCircle){
int midId;
if((currentCell.id+nextCircle)%2 == 1){ //判断有无中间环
pathCount++;
path[currentCell.id-1][nextCircle-1] = pathCount;
path[nextCircle-1][currentCell.id-1] = pathCount;
}else{
midId = (currentCell.id+nextCircle)/2;
float midX = (currentCell.x+cell[nextCircle-1].x)/2;
float midY = (currentCell.y+cell[nextCircle-1].y)/2;
Log.d("midY", "="+midY);
Log.d("cell[mid].y", "="+cell[midId].y);
if(midX == cell[midId-1].x || midY == cell[midId-1].y){ //判断中间环是否符合要求
pathCount++;
path[currentCell.id-1][midId-1] = pathCount;
path[midId-1][currentCell.id-1] = pathCount;
cell[midId-1].touched = currentCell.touched+1;//被触摸
cell[midId-1].bitmap = bEnd;//触摸后显示的图片
currentCell = cell[midId-1];
pathCount++;
path[midId-1][nextCircle-1] = pathCount;
path[nextCircle-1][midId-1] = pathCount;
}else{ //不符合要求
pathCount++;
path[currentCell.id-1][nextCircle-1] = pathCount;
path[nextCircle-1][currentCell.id-1] = pathCount;
}
}
cell[nextCircle-1].touched = currentCell.touched+1;//被触摸
cell[nextCircle-1].bitmap = bEnd;//触摸后显示的图片
}
/**
* 返回手势密码
* @return
*/
public int[] getLockPatternResult(){
int res[] = new int[9];
for(int i=0;i<9;i++)
res[i] = 0;
for(int i=0;i<9;i++){
if(cell[i].touched > 0)
res[cell[i].touched-1] = cell[i].id;
}
return res;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
- android -- 做个记录,以后方便回顾
- java 环境变量设置 留个记录方便以后查找
- 各种常用命令记录,做个记录,方便自己查阅
- git 用法记录,方便以后
- 写了个"网络连接管理"软件,以后做这事情方便了
- 做好记录---为了以后可以方便查询
- cvc个人记录[为了方便以后查看]
- 做了个统一的页面,方便以后使用,记得先备份原版首页再添加这个页面哦!
- Android调用jni全过程,方便以后操作。
- Android调用jni全过程,方便以后操作。
- android 安全机制验证机制总结(就本人目前的水平进行总结,记录以方便以后提高补充)
- 记录,方便以后查询rtl8881a,ecos,cmj-1
- 知识点要做好记录,方便以后自己查阅
- UI控件效果记录,方便以后使用查询
- eclipse环境安装(为了以后方便记录一下)
- 自己做个记录
- 开始做个记录
- Rand以后每个国家Sample50个记录
- linux 安装ffmpeg
- ServiceState学习
- KETTLE中,str2date 英文日期的转化
- PLSQL collection 示例 之 varray
- POJ 1182 食物链 (并查集)
- android -- 做个记录,以后方便回顾
- 2041.Runtime Error一般是数组不够大,Time Limit Exceeded一般是超时
- Apache下开启SSI配置使shtml支持include包含
- 如何获得客户端的真实IP
- linux编程
- [wikioi2930]填报志愿(裸题)
- 关于项目的风险控制
- 普通Java工程转换成maven工程
- SOJ.分数排名查询