編輯:關於Android編程
package com.example.patternlock; 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.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class LockView extends View { private boolean inited = false; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);// 抗鋸齒 Paint pressPaint = new Paint(); //按下時的畫筆 Paint errorPaint = new Paint(); //錯誤時的畫筆 private Bitmap bitmapPointError; private Bitmap bitmapPointPress; private Bitmap bitmapPointNormal; private float bitmapR; // 點的半徑 private boolean isDraw = false; //是否正在繪制 float mouseX, mouseY; private Point [][] points = new Point[3][3]; private ArrayListpointList = new ArrayList (); //保存經過的點 private ArrayList passList = new ArrayList (); private OnDrawFinishedListener listener; public LockView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub } public LockView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public LockView(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public boolean onTouchEvent(MotionEvent event) { mouseX = event.getX(); mouseY = event.getY(); int [] ij; int i , j; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: resetPoints(); ij = getSelectedPoint(); if(ij != null){ isDraw = true; i = ij[0]; j = ij[1]; points[i][j].state = Point.STATE_PRESS; pointList.add(points[i][j]); passList.add(i * 3 + j); } break; case MotionEvent.ACTION_MOVE: if(isDraw){ ij = getSelectedPoint(); if(ij != null){ i = ij[0]; j = ij[1]; if(!pointList.contains(points[i][j])){ points[i][j].state = Point.STATE_PRESS; pointList.add(points[i][j]); passList.add(i * 3 + j); } } } break; case MotionEvent.ACTION_UP: boolean valid = false; if(listener != null && isDraw){ valid = listener.OnDrawFinished(passList); } if(!valid){ for (Point p:pointList) { p.state = Point.STATE_ERROR; } } isDraw = false; break; default: break; } this.postInvalidate(); return true; } private int[] getSelectedPoint() { Point pMouse = new Point(mouseX,mouseY); for (int i = 0; i < points.length; i++) { for (int j = 0; j < points[i].length; j++) { if(points[i][j].distance(pMouse) < bitmapR){ int [] result = new int [2]; result[0] = i; result[1] = j; return result; } } } return null; } public void resetPoints() { passList.clear(); pointList.clear(); for (int i = 0; i < points.length; i++) { for (int j = 0; j < points[i].length; j++) { points[i][j].state = Point.STATE_NORMOL; } } this.postInvalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(!inited){ init(); } drawPoints(canvas); if(pointList.size() > 0){ //畫線 2->3,3->5 ... Point a = pointList.get(0); for (int i = 1;i < pointList.size(); i++) { Point b = pointList.get(i); drawLine(canvas, a, b); a = b; } if(isDraw){ // 畫最後一個點 drawLine(canvas, a, new Point(mouseX, mouseY)); } } } private void drawLine(Canvas canvas, Point a, Point b) { if(a.state == Point.STATE_ERROR){ canvas.drawLine(a.x, a.y, b.x, b.y, errorPaint); } else if(a.state == Point.STATE_PRESS){ canvas.drawLine(a.x, a.y, b.x, b.y, pressPaint); } } private void drawPoints(Canvas canvas) { for (int i = 0; i < points.length; i++) { for (int j = 0; j < points[i].length; j++) { if(points[i][j].state == Point.STATE_NORMOL){ // normol canvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint); } else if(points[i][j].state == Point.STATE_PRESS){ // press canvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint); } else{ // error canvas.drawBitmap(bitmapPointError, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint); } } } } private void init() { pressPaint.setColor(Color.YELLOW); pressPaint.setStrokeWidth(4); errorPaint.setColor(Color.RED); errorPaint.setStrokeWidth(4); bitmapPointError = BitmapFactory.decodeResource(getResources(), R.drawable.error); bitmapPointNormal = BitmapFactory.decodeResource(getResources(), R.drawable.normal); bitmapPointPress = BitmapFactory.decodeResource(getResources(), R.drawable.press); bitmapR = bitmapPointError.getWidth() / 2; //三種點的大小一樣 int width = getWidth(); int height = getHeight(); int offset = Math.abs(width - height) / 2; int offsetX, offsetY; int space; if(width > height){ space = height / 4; offsetX = offset; offsetY = 0; } else{ space = width / 4; offsetX = 0; offsetY = offset; } points[0][0] = new Point(offsetX +space , offsetY + space); points[0][1] = new Point(offsetX + 2*space , offsetY + space); points[0][2] = new Point(offsetX + 3 * space , offsetY + space); points[1][0] = new Point(offsetX +space, offsetY + 2 * space); points[1][1] = new Point(offsetX + 2 * space , offsetY + 2 * space); points[1][2] = new Point(offsetX + 3 * space , offsetY + 2 * space); points[2][0] = new Point(offsetX +space, offsetY + 3 * space); points[2][1] = new Point(offsetX + 2 * space , offsetY + 3 * space); points[2][2] = new Point(offsetX + 3 * space , offsetY + 3 * space); inited = true; //初始化完成 } public interface OnDrawFinishedListener{ boolean OnDrawFinished(List passList); } public void setOnDrawFinishedListener(OnDrawFinishedListener listener){ this.listener = listener; } }
package com.jikexueyuan.screenlock; import android.content.Intent; import android.content.SharedPreferences; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.util.List; public class SettingActivity extends ActionBarActivity { ListpassList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); final GestureLock lock = (GestureLock)findViewById(R.id.LockView); Button btn_reset = (Button)findViewById(R.id.btn_reset); Button btn_save = (Button)findViewById(R.id.btn_save); lock.setOnDrawFinishedListener(new GestureLock.OnDrawFinishedListener() { @Override public boolean OnDrawFinished(List passList) { if (passList.size() < 3) { Toast.makeText(SettingActivity.this, 密碼不能少於3個點, Toast.LENGTH_SHORT).show(); return false; } else { SettingActivity.this.passList = passList; return true; } } }); btn_reset.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lock.resetPoints(); } }); btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (passList != null) { StringBuilder sb = new StringBuilder(); for (Integer i : passList) { sb.append(i); } SharedPreferences sp = SettingActivity.this.getSharedPreferences(password, SettingActivity.this.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString(password, sb.toString()); editor.commit(); Toast.makeText(SettingActivity.this, 保存完成, Toast.LENGTH_SHORT).show(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_setting, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
package com.example.patternlock; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.widget.Toast; import java.util.List; import com.example.patternlock.LockView.OnDrawFinishedListener; public class LockActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lock); SharedPreferences sp = getSharedPreferences(password, this.MODE_PRIVATE); final String password = sp.getString(password, ); LockView lock = (LockView)findViewById(R.id.LockView); lock.setOnDrawFinishedListener(new OnDrawFinishedListener() { @Override public boolean OnDrawFinished(ListpassList) { StringBuilder sb = new StringBuilder(); for (Integer i : passList) { sb.append(i); } if (sb.toString().equals(password)){ Toast.makeText(LockActivity.this, 正確, Toast.LENGTH_SHORT).show(); return true; } else { Toast.makeText(LockActivity.this, 錯誤, Toast.LENGTH_SHORT).show(); return false; } } }); } }
一、前言 Android 中解決滑動的方案有2種:外部攔截法 和內部攔截法。 滑動沖突也存在2種場景: 橫豎滑動沖突、同向滑動沖突。 所以我就寫了4個例子來學習如何解決滑
(一).前言: 話說RecyclerView已經面市很久,也在很多應用中得到廣泛的使用,在整個開發者圈子裡面也擁有很不錯的口碑,那說明RecyclerVi
新版本的微信和QQ上引入的滑動刪除功能是現在比較流行的一個功能。其實這個滑動刪除的控件,github上已經有了,是一個熱門的開源框架SwipeListView。不過,這個
下面這張圖片是在google官網上下載的關於android系統的體系結構圖: 組件所使用的C、C++庫的集合,一般說來,android應用開發者不能直接調