編輯:關於Android編程
本文介紹九宮格程序的設計代碼。
一.相關介紹
(一)效果顯示
1.程序剛運行時的效果:
2.在頁面上點擊選擇並滑動時的畫面
3.選擇密碼之後的顯示
(二)功能介紹
1.點擊某圓圈後,在該圓圈的中心添加一個實行的小圓。
2.頁面滑動出現一條跟隨的線。
3.滑動到另一個圓圈時,產生一條連接的直線。
4.選擇的圓圈點數大於等於4個後,手指抬起,就會保存密碼。
4.選擇的圓圈的數是最大值後,馬上保存密碼。
(三)涉及到的知識點
本示例使用的是自定義的View來繪制九宮格,並保存圖像,這裡的九個點分別代表的是九個數值,獲取到對應的數值證明繪制了那個點。
程序中使用到的知識:
1、圖像的描繪,圓和點的描繪,線的描繪
2、位置的判斷,判斷用戶點的位置是否在某一個圓內
3、保存數據和相關判斷
二.程序設計
(一)自定義View的設計
package com.lwz.gongge; 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; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2016/10/28 0028. */ public class NineGridView extends View { //構造方法 public NineGridView(Context context) { super(context); init(); } //構造方法 public NineGridView(Context context, AttributeSet attrs) { super(context, attrs); init(); } //定義一個畫實心圓的畫筆 Paint paintCircle; //定義一個畫線的畫筆 Paint paintLine; //定義一個寬度值,大概是屏幕的四分之一,代表的是每一個圓點間的x軸距離 int width; //定義一個背景顏色 int backColor; //定義一個集合用來存放點擊過的圓點0到8表示九個點 List<Integer> listPassword = new ArrayList<>(); //觸屏的位置 float currX, currY; //密碼的個數 int minPassNum = 4; int maxPassNum = 9; //初始化 private void init() { //定義背景顏色 backColor = Color.rgb(0x17, 0x16, 0x25); //實例化畫筆,並作基本設置 paintLine = new Paint(); paintLine.setAntiAlias(true); paintLine.setDither(true); paintLine.setColor(Color.rgb(0x37, 0x91, 0xe6)); paintCircle = new Paint(); paintCircle.setAntiAlias(true); paintCircle.setDither(true); paintCircle.setColor(backColor); } //丈量屏幕時回調的方法,在這個方法內可以取得屏幕的寬度 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getWidth() / 4; } //屏幕圖像繪制回調的方法 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //設置屏幕的顏色,(清屏) canvas.drawColor(backColor); //畫線,如果數據集合內有數據才能去畫線 if (listPassword.size() > 0) { //求出最後畫的那個點來做畫線 //這裡求得是坐標點 int x = listPassword.get(listPassword.size() - 1) % 3 + 1;//x軸的方向 int y = listPassword.get(listPassword.size() - 1) / 3 + 1;//y軸的方向 //設置畫線的大小 paintLine.setStrokeWidth(8); //畫線,從具體點的位置到觸屏的位置 canvas.drawLine(x * width, y * width, currX, currY, paintLine); //再畫一個圓覆蓋掉圓圈內的那些線 canvas.drawCircle(x * width, y * width, width / 3, paintCircle); //如果集合的數據中還有其他的點的數據 if (listPassword.size() > 1) { //按順序畫線 for (int i = 0; i < listPassword.size() - 1; i++) {//防止越界 //獲取當前的一個i和後面的一個i //前一個點的坐標點 int x1 = listPassword.get(i) % 3 + 1; int y1 = listPassword.get(i) / 3 + 1; //後一個點的坐標點 int x2 = listPassword.get(i + 1) % 3 + 1; int y2 = listPassword.get(i + 1) / 3 + 1; //設置畫筆的大小 paintLine.setStrokeWidth(8); //畫線,從上一個點的位置到下一個點的位置 canvas.drawLine(x1 * width, y1 * width, x2 * width, y2 * width, paintLine); //再畫一個圓覆蓋掉圓圈內的那些線,這裡覆蓋的是後面的一個圓的線 canvas.drawCircle(x1 * width, y1 * width, width / 3, paintCircle); } } } //繪制九個圓圈,用的是線 //設置寬度 paintLine.setStrokeWidth(2); //設置空心必須要的 paintLine.setStyle(Paint.Style.STROKE); //開始畫圓9個,這裡圓的半徑暫時設置為圓距離的3分之一 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { //一個參數是圓點的x軸的坐標值 //二個參數是圓點的y軸的坐標值 canvas.drawCircle(width * (i + 1), width * (j + 1), width / 3, paintLine); //這裡的圖像的y軸上不一定是在中心,但是整體是個正方形,效果差不多就可以了 } } //繪制實心圓在圓圈裡面,顏色和外面的圓圈的顏色是一樣的,用同一只筆 //這裡要判斷你劃過幾個點,對集合進行遍歷 //設置實心樣式 paintLine.setStyle(Paint.Style.FILL); for (int i = 0; i < listPassword.size(); i++) { //取出集合裡面的數 int p = listPassword.get(i); int x = p % 3; int y = p / 3; //一個參數是圓點的x軸的坐標值 //二個參數是圓點的y軸的坐標值 canvas.drawCircle(width * (x + 1), width * (y + 1), width / 6, paintLine); } } //觸摸屏幕的監聽事件 @Override public boolean onTouchEvent(MotionEvent event) { //獲取用戶點擊的坐標位置 float x = event.getX(); float y = event.getY(); //判斷用戶的行為並作相應的操作 switch (event.getAction()) { case MotionEvent.ACTION_DOWN://觸屏時 //判斷用戶是否點擊在某個圓點范圍內 if (connetCircle(x, y) != -1) { //更新位置 currX = x; currY = y; //把這個點的位置添加到存放數據的集合中 listPassword.add(connetCircle(x, y)); } break; case MotionEvent.ACTION_UP://手指抬起時 //如果密碼的值到到達最小位數後保存密碼給主頁面 if (listPassword.size() >= minPassNum) { //如果另一邊實現了監聽事件,那麼就給他數據 if (listener != null) { //把密碼傳遞過去 listener.toListenerThePassword(getPasswordString()); } } //清空數據 listPassword.clear(); break; case MotionEvent.ACTION_MOVE://手指移動時 //更新位置 currX = x; currY = y; //移動到其他的圓中,那麼就添加數據到集合中 //獲取該點的位置 int point = connetCircle(x, y); //如果這個點是在圓內,並且數據裡面不包含這個點的值,那麼就添加這個點的值到集合中 if (point != -1 && !listPassword.contains((Integer) point)) { listPassword.add(point); } //如果密碼的值到到最大值後保存密碼給主頁面 if (listPassword.size() >= maxPassNum) { //如果另一邊實現了監聽事件,那麼就給他數據 if (listener != null) { //把密碼傳遞過去 listener.toListenerThePassword(getPasswordString()); } break; } } //不管是上面是什麼行為最後都要刷新一下屏幕 invalidate();//屏幕重繪 return true; } //判斷用戶點擊的地方是否在某一個圓點內 private boolean isInCircle(float x, float y, float cx, float cy) { //x、y代表的是坐標位置 //cx、cy代表的是圓坐標位置 //圓點半徑是width/3 //如果點擊的位置減去圓心的位置的平方小於半徑的平方那麼這個點是在圓內的 return (x - cx) * (x - cx) + (y - cy) * (y - cy) < (width / 3) * (width / 3); } //判斷用戶點擊的地方是否在九個圓點的哪一個圓點內 private int connetCircle(float x, float y) { //x、y代表的是坐標位置 //依次判斷每個圓圈看看是否在它的裡面 //圓點的坐標位置-->(width,width)--(2*width,width)--(3*width,width) //--->(width,2*width)--(2*width,2*width)--(3*width,2*width) //--->(width,3*width)--(2*width,3*width)--(3*width,3*width) for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (isInCircle(x, y, width * (j + 1), width * (i + 1))) {//(i,j) //如果點擊是圓,就把這個點的值添加到集合中 //0 1 2 (0,0)/(0,1)/(0/2) //3 4 5 (1,0)/(1,1)/(1/2) //6 7 8 (2,0)/(2,1)/(2/2) //如果是7,那麼游標值(2,1) //返回該點的值 return (3 * i + j); } } } //如果不在九個圓點位置就返回-1 return -1; } //創建一個回調接口,讓主頁面監聽這個事件 interface onFinishListener { void toListenerThePassword(String s); } //設置一個監聽接口的對象 onFinishListener listener; //設置監聽接口的方法 public void setListener(onFinishListener listener) { this.listener = listener; } //獲取密碼的字符串 public String getPasswordString() { //定義密碼的字符串 String pass = ""; //取出集合裡面的密碼的數字 for (int i = 0; i < listPassword.size(); i++) { pass += listPassword.get(i); } return pass; } }
(二)主方法調用這個View的類
package com.lwz.gongge; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; public class MainActivity extends AppCompatActivity { //自定義View傳遞過來的密碼 String password = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //定義自定義的View並實例化 NineGridView nine = new NineGridView(this); //顯示自定義的View setContentView(nine); //通過監聽方法來獲取自定義傳來的密碼 //給視圖設置監聽事件 nine.setListener(new NineGridView.onFinishListener() { @Override public void toListenerThePassword(String pass) { //這裡的pass是自定義View裡面,傳過來的數據 password = pass; //土司密碼 Toast.makeText(MainActivity.this, "密碼:" + password, Toast.LENGTH_SHORT).show(); } }); } }
上面就是九宮格程序設計的代碼了。這裡沒有用到xml的布局文件,都是用代碼實現的。
完成自定義View後,調用和使用都是比較簡單的,可以作為一個工具類使用,獲取到自定義View傳過來的密碼,可以做其他保存操作,比如保存到本地文件或數據庫中,這裡只是做了土司操作,讓用戶看到效果。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
Android插件化基礎(4),動態啟動插件中的ActivityAuthor:鄭海波-莫川簡介如何動態啟動插件中的Activity呢?我們首先分析,啟動插件中的Activ
由於IPC機制牽扯的東西比較多,所以這裡將分為一個系列進行總結主要介紹內如如下:IPC簡介 Android中的多進程模式開啟多進程模式 多進程模式的運行機制 IPC基礎概
在Android群裡,經常會有人問我,Android Log是怎麼用的,今天我就把從網上以及SDK裡東拼西湊過來,讓大家先一睹為快,希望對大家入門Android Log有
在Android 系統移植做自己的移動設備,肯定會遇到更改開機或者關機畫面,配置自己產品logo 這點是必須的,這些都要