Android九宮格程序設(shè)計(jì)代碼
本文介紹Android九宮格程序的設(shè)計(jì)代碼,供大家參考,具體內(nèi)容如下
一.相關(guān)介紹
(一)效果顯示
1.程序剛運(yùn)行時(shí)的效果:

2.在頁(yè)面上點(diǎn)擊選擇并滑動(dòng)時(shí)的畫面

3.選擇密碼之后的顯示

(二)功能介紹
1.點(diǎn)擊某圓圈后,在該圓圈的中心添加一個(gè)實(shí)行的小圓。
2.頁(yè)面滑動(dòng)出現(xiàn)一條跟隨的線。
3.滑動(dòng)到另一個(gè)圓圈時(shí),產(chǎn)生一條連接的直線。
4.選擇的圓圈點(diǎn)數(shù)大于等于4個(gè)后,手指抬起,就會(huì)保存密碼。
4.選擇的圓圈的數(shù)是最大值后,馬上保存密碼。
(三)涉及到的知識(shí)點(diǎn)
本示例使用的是自定義的View來(lái)繪制九宮格,并保存圖像,這里的九個(gè)點(diǎn)分別代表的是九個(gè)數(shù)值,獲取到對(duì)應(yīng)的數(shù)值證明繪制了那個(gè)點(diǎn)。
程序中使用到的知識(shí):
1、圖像的描繪,圓和點(diǎn)的描繪,線的描繪
2、位置的判斷,判斷用戶點(diǎn)的位置是否在某一個(gè)圓內(nèi)
3、保存數(shù)據(jù)和相關(guān)判斷
二.程序設(shè)計(jì)
(一)自定義View的設(shè)計(jì)
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 {
//構(gòu)造方法
public NineGridView(Context context) {
super(context);
init();
}
//構(gòu)造方法
public NineGridView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
//定義一個(gè)畫實(shí)心圓的畫筆
Paint paintCircle;
//定義一個(gè)畫線的畫筆
Paint paintLine;
//定義一個(gè)寬度值,大概是屏幕的四分之一,代表的是每一個(gè)圓點(diǎn)間的x軸距離
int width;
//定義一個(gè)背景顏色
int backColor;
//定義一個(gè)集合用來(lái)存放點(diǎn)擊過(guò)的圓點(diǎn)0到8表示九個(gè)點(diǎn)
List<Integer> listPassword = new ArrayList<>();
//觸屏的位置
float currX, currY;
//密碼的個(gè)數(shù)
int minPassNum = 4;
int maxPassNum = 9;
//初始化
private void init() {
//定義背景顏色
backColor = Color.rgb(0x17, 0x16, 0x25);
//實(shí)例化畫筆,并作基本設(shè)置
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);
}
//丈量屏幕時(shí)回調(diào)的方法,在這個(gè)方法內(nèi)可以取得屏幕的寬度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getWidth() / 4;
}
//屏幕圖像繪制回調(diào)的方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//設(shè)置屏幕的顏色,(清屏)
canvas.drawColor(backColor);
//畫線,如果數(shù)據(jù)集合內(nèi)有數(shù)據(jù)才能去畫線
if (listPassword.size() > 0) {
//求出最后畫的那個(gè)點(diǎn)來(lái)做畫線
//這里求得是坐標(biāo)點(diǎn)
int x = listPassword.get(listPassword.size() - 1) % 3 + 1;//x軸的方向
int y = listPassword.get(listPassword.size() - 1) / 3 + 1;//y軸的方向
//設(shè)置畫線的大小
paintLine.setStrokeWidth(8);
//畫線,從具體點(diǎn)的位置到觸屏的位置
canvas.drawLine(x * width, y * width, currX, currY, paintLine);
//再畫一個(gè)圓覆蓋掉圓圈內(nèi)的那些線
canvas.drawCircle(x * width, y * width, width / 3, paintCircle);
//如果集合的數(shù)據(jù)中還有其他的點(diǎn)的數(shù)據(jù)
if (listPassword.size() > 1) {
//按順序畫線
for (int i = 0; i < listPassword.size() - 1; i++) {//防止越界
//獲取當(dāng)前的一個(gè)i和后面的一個(gè)i
//前一個(gè)點(diǎn)的坐標(biāo)點(diǎn)
int x1 = listPassword.get(i) % 3 + 1;
int y1 = listPassword.get(i) / 3 + 1;
//后一個(gè)點(diǎn)的坐標(biāo)點(diǎn)
int x2 = listPassword.get(i + 1) % 3 + 1;
int y2 = listPassword.get(i + 1) / 3 + 1;
//設(shè)置畫筆的大小
paintLine.setStrokeWidth(8);
//畫線,從上一個(gè)點(diǎn)的位置到下一個(gè)點(diǎn)的位置
canvas.drawLine(x1 * width, y1 * width, x2 * width, y2 * width, paintLine);
//再畫一個(gè)圓覆蓋掉圓圈內(nèi)的那些線,這里覆蓋的是后面的一個(gè)圓的線
canvas.drawCircle(x1 * width, y1 * width, width / 3, paintCircle);
}
}
}
//繪制九個(gè)圓圈,用的是線
//設(shè)置寬度
paintLine.setStrokeWidth(2);
//設(shè)置空心必須要的
paintLine.setStyle(Paint.Style.STROKE);
//開(kāi)始畫圓9個(gè),這里圓的半徑暫時(shí)設(shè)置為圓距離的3分之一
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//一個(gè)參數(shù)是圓點(diǎn)的x軸的坐標(biāo)值
//二個(gè)參數(shù)是圓點(diǎn)的y軸的坐標(biāo)值
canvas.drawCircle(width * (i + 1), width * (j + 1), width / 3, paintLine);
//這里的圖像的y軸上不一定是在中心,但是整體是個(gè)正方形,效果差不多就可以了
}
}
//繪制實(shí)心圓在圓圈里面,顏色和外面的圓圈的顏色是一樣的,用同一只筆
//這里要判斷你劃過(guò)幾個(gè)點(diǎn),對(duì)集合進(jìn)行遍歷
//設(shè)置實(shí)心樣式
paintLine.setStyle(Paint.Style.FILL);
for (int i = 0; i < listPassword.size(); i++) {
//取出集合里面的數(shù)
int p = listPassword.get(i);
int x = p % 3;
int y = p / 3;
//一個(gè)參數(shù)是圓點(diǎn)的x軸的坐標(biāo)值
//二個(gè)參數(shù)是圓點(diǎn)的y軸的坐標(biāo)值
canvas.drawCircle(width * (x + 1), width * (y + 1), width / 6, paintLine);
}
}
//觸摸屏幕的監(jiān)聽(tīng)事件
@Override
public boolean onTouchEvent(MotionEvent event) {
//獲取用戶點(diǎn)擊的坐標(biāo)位置
float x = event.getX();
float y = event.getY();
//判斷用戶的行為并作相應(yīng)的操作
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://觸屏?xí)r
//判斷用戶是否點(diǎn)擊在某個(gè)圓點(diǎn)范圍內(nèi)
if (connetCircle(x, y) != -1) {
//更新位置
currX = x;
currY = y;
//把這個(gè)點(diǎn)的位置添加到存放數(shù)據(jù)的集合中
listPassword.add(connetCircle(x, y));
}
break;
case MotionEvent.ACTION_UP://手指抬起時(shí)
//如果密碼的值到到達(dá)最小位數(shù)后保存密碼給主頁(yè)面
if (listPassword.size() >= minPassNum) {
//如果另一邊實(shí)現(xiàn)了監(jiān)聽(tīng)事件,那么就給他數(shù)據(jù)
if (listener != null) {
//把密碼傳遞過(guò)去
listener.toListenerThePassword(getPasswordString());
}
}
//清空數(shù)據(jù)
listPassword.clear();
break;
case MotionEvent.ACTION_MOVE://手指移動(dòng)時(shí)
//更新位置
currX = x;
currY = y;
//移動(dòng)到其他的圓中,那么就添加數(shù)據(jù)到集合中
//獲取該點(diǎn)的位置
int point = connetCircle(x, y);
//如果這個(gè)點(diǎn)是在圓內(nèi),并且數(shù)據(jù)里面不包含這個(gè)點(diǎn)的值,那么就添加這個(gè)點(diǎn)的值到集合中
if (point != -1 && !listPassword.contains((Integer) point)) {
listPassword.add(point);
}
//如果密碼的值到到最大值后保存密碼給主頁(yè)面
if (listPassword.size() >= maxPassNum) {
//如果另一邊實(shí)現(xiàn)了監(jiān)聽(tīng)事件,那么就給他數(shù)據(jù)
if (listener != null) {
//把密碼傳遞過(guò)去
listener.toListenerThePassword(getPasswordString());
}
break;
}
}
//不管是上面是什么行為最后都要刷新一下屏幕
invalidate();//屏幕重繪
return true;
}
//判斷用戶點(diǎn)擊的地方是否在某一個(gè)圓點(diǎn)內(nèi)
private boolean isInCircle(float x, float y, float cx, float cy) {
//x、y代表的是坐標(biāo)位置
//cx、cy代表的是圓坐標(biāo)位置
//圓點(diǎn)半徑是width/3
//如果點(diǎn)擊的位置減去圓心的位置的平方小于半徑的平方那么這個(gè)點(diǎn)是在圓內(nèi)的
return (x - cx) * (x - cx) + (y - cy) * (y - cy) < (width / 3) * (width / 3);
}
//判斷用戶點(diǎn)擊的地方是否在九個(gè)圓點(diǎn)的哪一個(gè)圓點(diǎn)內(nèi)
private int connetCircle(float x, float y) {
//x、y代表的是坐標(biāo)位置
//依次判斷每個(gè)圓圈看看是否在它的里面
//圓點(diǎn)的坐標(biāo)位置-->(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)
//如果點(diǎn)擊是圓,就把這個(gè)點(diǎn)的值添加到集合中
//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,那么游標(biāo)值(2,1)
//返回該點(diǎn)的值
return (3 * i + j);
}
}
}
//如果不在九個(gè)圓點(diǎn)位置就返回-1
return -1;
}
//創(chuàng)建一個(gè)回調(diào)接口,讓主頁(yè)面監(jiān)聽(tīng)這個(gè)事件
interface onFinishListener {
void toListenerThePassword(String s);
}
//設(shè)置一個(gè)監(jiān)聽(tīng)接口的對(duì)象
onFinishListener listener;
//設(shè)置監(jiān)聽(tīng)接口的方法
public void setListener(onFinishListener listener) {
this.listener = listener;
}
//獲取密碼的字符串
public String getPasswordString() {
//定義密碼的字符串
String pass = "";
//取出集合里面的密碼的數(shù)字
for (int i = 0; i < listPassword.size(); i++) {
pass += listPassword.get(i);
}
return pass;
}
}
(二)主方法調(diào)用這個(gè)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傳遞過(guò)來(lái)的密碼
String password = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//定義自定義的View并實(shí)例化
NineGridView nine = new NineGridView(this);
//顯示自定義的View
setContentView(nine);
//通過(guò)監(jiān)聽(tīng)方法來(lái)獲取自定義傳來(lái)的密碼
//給視圖設(shè)置監(jiān)聽(tīng)事件
nine.setListener(new NineGridView.onFinishListener() {
@Override
public void toListenerThePassword(String pass) {
//這里的pass是自定義View里面,傳過(guò)來(lái)的數(shù)據(jù)
password = pass;
//土司密碼
Toast.makeText(MainActivity.this, "密碼:" + password, Toast.LENGTH_SHORT).show();
}
});
}
}
上面就是九宮格程序設(shè)計(jì)的代碼了。這里沒(méi)有用到xml的布局文件,都是用代碼實(shí)現(xiàn)的。
完成自定義View后,調(diào)用和使用都是比較簡(jiǎn)單的,可以作為一個(gè)工具類使用,獲取到自定義View傳過(guò)來(lái)的密碼,可以做其他保存操作,比如保存到本地文件或數(shù)據(jù)庫(kù)中,這里只是做了土司操作,讓用戶看到效果。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 九宮格的實(shí)現(xiàn)方法
- android 九宮格滑動(dòng)解鎖開(kāi)機(jī)實(shí)例源碼學(xué)習(xí)
- Android實(shí)現(xiàn)九宮格(GridView中各項(xiàng)平分空間)的方法
- Android開(kāi)發(fā)之實(shí)現(xiàn)GridView支付寶九宮格
- Android編程之九宮格實(shí)現(xiàn)方法實(shí)例分析
- Android實(shí)現(xiàn)九宮格解鎖
- 使用Android自定義控件實(shí)現(xiàn)滑動(dòng)解鎖九宮格
- Android打造流暢九宮格抽獎(jiǎng)活動(dòng)效果
- 輕松實(shí)現(xiàn)Android自定義九宮格圖案解鎖
- Android九宮格手勢(shì)密碼代碼設(shè)計(jì)
- Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格示例
相關(guān)文章
Android使用JobScheduler定期推送本地通知實(shí)例代碼
本篇文章主要介紹了Android使用JobScheduler定期推送本地通知實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
java從輸入流中獲取數(shù)據(jù)并返回字節(jié)數(shù)組示例
這篇文章主要介紹了java從輸入流中獲取數(shù)據(jù)并以字節(jié)數(shù)組返回,這是一個(gè)常用的方法,以后可以直接拿來(lái)用。這種輸入流可以來(lái)自Android本地,也可以來(lái)自網(wǎng)絡(luò)2014-01-01
Android實(shí)現(xiàn)Service重啟的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Service重啟的方法,涉及Android操作Service組件實(shí)現(xiàn)服務(wù)重啟的功能,需要的朋友可以參考下2015-05-05
Android 7.0 運(yùn)行時(shí)權(quán)限彈窗問(wèn)題的解決
這篇文章主要介紹了Android 7.0 運(yùn)行時(shí)權(quán)限彈窗問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Android 開(kāi)發(fā)中fragment預(yù)加載問(wèn)題
這篇文章主要介紹了Android 開(kāi)發(fā)中fragment預(yù)加載問(wèn)題的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01
android自定義ListView實(shí)現(xiàn)底部View自動(dòng)隱藏和消失的功能
本篇文章主要介紹了android自定義ListView實(shí)現(xiàn)底部View自動(dòng)隱藏和消失的功能 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
Android Chronometer控件實(shí)現(xiàn)計(jì)時(shí)器函數(shù)詳解
這篇文章主要為大家詳細(xì)介紹了Android Chronometer控件實(shí)現(xiàn)計(jì)時(shí)器函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-04-04
adb通過(guò)wifi連接android設(shè)備流程解析
這篇文章主要介紹了adb通過(guò)wifi連接android設(shè)備流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
Android開(kāi)發(fā)中使用外部應(yīng)用獲取SD卡狀態(tài)的方法
這篇文章主要介紹了Android開(kāi)發(fā)中使用外部應(yīng)用獲取SD卡狀態(tài)的方法,簡(jiǎn)單分析了Android監(jiān)聽(tīng)SD卡狀態(tài)的方法,并結(jié)合實(shí)例形式分析了Android外部應(yīng)用獲取SD卡狀態(tài)的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11

