欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android九宮格程序設(shè)計(jì)代碼

 更新時(shí)間:2020年08月20日 14:51:41   作者:崢嶸life  
這篇文章主要為大家詳細(xì)介紹了Android九宮格程序設(shè)計(jì)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文介紹Android九宮格程序的設(shè)計(jì)代碼,供大家參考,具體內(nèi)容如下

一.相關(guān)介紹

(一)效果顯示

1.程序剛運(yùn)行時(shí)的效果:

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

3.選擇密碼之后的顯示

(二)功能介紹

1.點(diǎn)擊某圓圈后,在該圓圈的中心添加一個(gè)實(shí)行的小圓。
2.頁(yè)面滑動(dòng)出現(xiàn)一條跟隨的線(xiàn)。
3.滑動(dòng)到另一個(gè)圓圈時(shí),產(chǎn)生一條連接的直線(xià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)的描繪,線(xiàn)的描繪
2、位置的判斷,判斷用戶(hù)點(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è)畫(huà)實(shí)心圓的畫(huà)筆
 Paint paintCircle;
 //定義一個(gè)畫(huà)線(xiàn)的畫(huà)筆
 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í)例化畫(huà)筆,并作基本設(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);

 //畫(huà)線(xiàn),如果數(shù)據(jù)集合內(nèi)有數(shù)據(jù)才能去畫(huà)線(xiàn)
 if (listPassword.size() > 0) {
 //求出最后畫(huà)的那個(gè)點(diǎn)來(lái)做畫(huà)線(xiàn)
 //這里求得是坐標(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è)置畫(huà)線(xiàn)的大小
 paintLine.setStrokeWidth(8);
 //畫(huà)線(xiàn),從具體點(diǎn)的位置到觸屏的位置
 canvas.drawLine(x * width, y * width, currX, currY, paintLine);
 //再畫(huà)一個(gè)圓覆蓋掉圓圈內(nèi)的那些線(xiàn)
 canvas.drawCircle(x * width, y * width, width / 3, paintCircle);

 //如果集合的數(shù)據(jù)中還有其他的點(diǎn)的數(shù)據(jù)
 if (listPassword.size() > 1) {
 //按順序畫(huà)線(xiàn)
 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è)置畫(huà)筆的大小
  paintLine.setStrokeWidth(8);
  //畫(huà)線(xiàn),從上一個(gè)點(diǎn)的位置到下一個(gè)點(diǎn)的位置
  canvas.drawLine(x1 * width, y1 * width, x2 * width, y2 * width, paintLine);
  //再畫(huà)一個(gè)圓覆蓋掉圓圈內(nèi)的那些線(xiàn),這里覆蓋的是后面的一個(gè)圓的線(xiàn)
  canvas.drawCircle(x1 * width, y1 * width, width / 3, paintCircle);
 }
 }

 }


 //繪制九個(gè)圓圈,用的是線(xiàn)
 //設(shè)置寬度
 paintLine.setStrokeWidth(2);
 //設(shè)置空心必須要的
 paintLine.setStyle(Paint.Style.STROKE);
 //開(kāi)始畫(huà)圓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) {
 //獲取用戶(hù)點(diǎn)擊的坐標(biāo)位置
 float x = event.getX();
 float y = event.getY();

 //判斷用戶(hù)的行為并作相應(yīng)的操作
 switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN://觸屏?xí)r
 //判斷用戶(hù)是否點(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;
 }

 //判斷用戶(hù)點(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);
 }

 //判斷用戶(hù)點(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的類(lèi)

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è)工具類(lèi)使用,獲取到自定義View傳過(guò)來(lái)的密碼,可以做其他保存操作,比如保存到本地文件或數(shù)據(jù)庫(kù)中,這里只是做了土司操作,讓用戶(hù)看到效果。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論