多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android開發-自定義View-AndroidStudio(二十六)數獨(3)Dialog監聽

Android開發-自定義View-AndroidStudio(二十六)數獨(3)Dialog監聽

來源:程序員人生   發布時間:2017-03-17 09:54:15 閱讀次數:5366次
轉載請注明出處:http://blog.csdn.net/iwanghang/
覺得博文有用,請點贊,請評論,請關注,謝謝!~


老規矩,先上GIF動態圖,看個效果,如果符合你的項目或肯定你要了解的內容,再往下看吧:

看1下代碼里面的K1,K2,K3,K4,K5,K6,就能夠了解函數運行的順序,最后在看1下setTileIfValid方法就能夠了。



KeyDialog.java:
package com.iwanghang.newview;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;

// 該類用于實現Dialog,實現自定義的對話框功能
public class KeyDialog extends Dialog {
    // 用來寄存代表對話框當中按鈕的對象
    private final View keys [] = new View[9];
    private final int used[];
    private NewView newView;

    // 構造函數的第2個參數當中保存著當前單元格已使用過的數字
    public KeyDialog(Context context, int [] used){
        super(context);
        this.used = used;
    }

    // 構造函數的第2個參數當中保存著當前單元格已使用過的數字
    public KeyDialog(Context context,int [] used,NewView newView){
        super(context);
        this.used = used;
        this.newView = newView;
    }

    // 當1個Dialog第1次顯示的時候,會調用其onCreate方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 設置對話框的標題
        setTitle("KeyDialog");
        // 用于為該Dialog設置布局文件
        setContentView(R.layout.keypad);
        //
        findViews();
        // 遍歷全部used數組
        for (int i = 0; i <used.length; i++) {
            if(used[i] != 0){
                System.out.println(used[i]);
                keys[used[i] - 1].setVisibility(View.INVISIBLE);
            }
        }
        // 為對話框當中所有的按鈕設置監聽器
        setListeners();
    }

    private void findViews() {
        keys[0] = findViewById(R.id.keypad_1);
        keys[1] = findViewById(R.id.keypad_2);
        keys[2] = findViewById(R.id.keypad_3);
        keys[3] = findViewById(R.id.keypad_4);
        keys[4] = findViewById(R.id.keypad_5);
        keys[5] = findViewById(R.id.keypad_6);
        keys[6] = findViewById(R.id.keypad_7);
        keys[7] = findViewById(R.id.keypad_8);
        keys[8] = findViewById(R.id.keypad_9);
    }






    // KeyDialog初始化的時候,設置數字按鍵監聽,K1
    private void setListeners() {
        // 遍歷全部keys數組
        for (int i = 0; i < keys.length; i++) {
            final int keyPress = i + 1;
            keys[i].setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    returnResult(keyPress); // 返回點擊的數字,K2
                }
            });
        }
    }
    // 通知NewView對象,刷新全部9宮格顯示的數據
    private void returnResult(int tile) {
        newView.setSelectedTile(tile); // 調用NewView中的方法,K3
        // 取消對話框的顯示
        dismiss();
    }




}
NewView.java:
package com.iwanghang.newview;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class NewView extends View{
    // 單元格的寬度和高度
    private float width;
    private float height;

    private int checkPoint = 1; // 當前關卡

    private MainActivity mainActivity = (MainActivity) getContext();

    //private Number number = new Number();
    private Number number = new Number(checkPoint);

    private int selectedX;
    private int selectedY;

    public NewView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NewView(MainActivity mainActivity) {
        super(mainActivity);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.width = w / 9f;
        this.height = h / 10f;
        super.onSizeChanged(w, h, oldw, oldh);
    }

    // 當Android系統需要繪制1個View對象時,就會調用該對象的onDraw
    @Override
    protected void onDraw(Canvas canvas) {
        System.out.println("AAA onDraw -----------------");
        // 畫背景
        Paint backgroundPaint = new Paint();
        backgroundPaint.setColor(getResources().getColor(R.color.colorBackground));
        canvas.drawRect(0,0,getWidth(),getHeight(),backgroundPaint);

        Paint darkPaint = new Paint();
        darkPaint.setColor(getResources().getColor(R.color.colorDark));

        Paint hilitePaint = new Paint();
        hilitePaint.setColor(getResources().getColor(R.color.colorHilite));

        Paint lightPaint = new Paint();
        lightPaint.setColor(getResources().getColor(R.color.colorLight));

        // 繪制9X9的網絡格
        // 兩條距離為1的直線,視覺上會有割裂的效果
        for (int i = 0; i < 9; i++) {
            canvas.drawLine(0, i*height, getWidth(), i*height, lightPaint);
            canvas.drawLine(0, i*height+1, getWidth(), i*height+1, hilitePaint);
            canvas.drawLine(i*width, 0, i*width, getHeight(), lightPaint);
            canvas.drawLine(i*width+1, 0, i*width+1, getHeight(), hilitePaint);
        }

        // 繪制3X3的網絡格
        for (int i = 0; i < 10; i++) {
            if (i % 3 != 0) {
                continue;
            }
            canvas.drawLine(0, i*height, getWidth(), i*height, darkPaint);
            canvas.drawLine(0, i*height+1, getWidth(), i*height+1, hilitePaint);
            canvas.drawLine(i*width, 0, i*width, getHeight(), darkPaint);
            //canvas.drawLine(i*width+1, 0, i*width+1, getHeight(), hilitePaint);
            canvas.drawLine(i*width, 1, i*width, getHeight(), hilitePaint);
        }

        // 繪制數字
        Paint numberPaint = new Paint();
        numberPaint.setColor(Color.BLACK);
        numberPaint.setStyle(Paint.Style.STROKE);
        numberPaint.setTextSize(height*0.75f);
        numberPaint.setTextAlign(Paint.Align.CENTER);
        numberPaint.setAntiAlias(true); // 抗鋸齒

        /**
         * 數字居中位置
         * x軸居中比較容易計算
         * y軸居中的計算,依賴于FontMetrics,大家很容易百度到相干的知識
         */
        Paint.FontMetrics fm = numberPaint.getFontMetrics();
        float x = width / 2;
        float y = height / 2 - (fm.ascent + fm.descent) / 2;

//        canvas.drawText("1", 0 * width + x, 0 * height + y, numberPaint);
//        canvas.drawText("2", 1 * width + x, 1 * height + y, numberPaint);
//        canvas.drawText("3", 2 * width + x, 2 * height + y, numberPaint);
//        canvas.drawText("4", 3 * width + x, 3 * height + y, numberPaint);
//        canvas.drawText("5", 4 * width + x, 4 * height + y, numberPaint);

//        /**
//         * 根據Number類中的數組,繪制數字
//         */
//        for (int i = 0; i < 9; i++) {
//            for (int j = 0; j < 9; j++) {
//                canvas.drawText(number.getTileString(i,j), i*width+x, j*height+y, numberPaint);
//                mainActivity.playSound();
//                handler.sendEmptyMessageDelayed(0, 200); // 每次重繪后,等待200毫秒,給handler發消息
//            }
//        }

        /**
         * 繪制1個刷新文字
         */
        canvas.drawText("刷新",4*width+x,9*height+y,numberPaint);

        /**
         * 繪制關卡文字
         */
        Paint strPaint = new Paint();
        strPaint.setTextSize(height*0.5f);
        strPaint.setAntiAlias(true); // 抗鋸齒
        canvas.drawText("第" + checkPoint + "關",6*width+x,9*height+y,strPaint);

        //super.onDraw(canvas);
//        canvas.drawText(number.getTileString(numberX,numberY), numberX*width+x, numberY*height+y, numberPaint);
//        System.out.println("numberY = " + numberY);
//        if (numberY < 9){
//            if (number.getTileString(numberX,numberY) != ""){
//                mainActivity.playSound();
//                handler.sendEmptyMessageDelayed(0, 200); // 每次重繪后,等待200毫秒,給handler發消息
//            }else {
//                handler.sendEmptyMessageDelayed(0, 0); // 每次重繪后,等待500毫秒,給handler發消息
//            }
//        }


        /**
         * 優先繪制上1次繪制過的數字
         */
        int numberIndexOld = 0;
        int ii = 0;
        int jj = 0;
        if (numberIndex != 0){ // 首次繪制,沒有上1次繪制過的數字,所以不進入這個方法
            System.out.println("AAA 優先繪制上1次繪制過的數字 numberIndex = " + numberIndex);
            outterLoop1:
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    canvas.drawText(number.getTileString(i,j), i*width+x, j*height+y, numberPaint);
                    System.out.println("AAA 優先繪制上1次繪制過的數字 number = " + number.getTileString(i,j) + " | i = " + i
                            + " | j = " + j + " | numberIndexOld = " + numberIndexOld);
                    if (numberIndexOld == (numberIndex⑴)){
                        ii = i;
                        jj = j;
                        break outterLoop1;
                    }
                    numberIndexOld = numberIndexOld + 1 ;
                }
            }
            jj = jj + 1;
            if (jj == 9){
                jj = 0;
                ii = ii + 1;
            }
        }

        int getOld = 0;
        /**
         * 根據Number類中的數組,繪制數字
         */
        System.out.println("AAA0 繪制數字 jj = " + jj + " | ii = " + ii);
        outterLoop2:
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (getOld == 0){ // 繼續上1次繪制的數字的i和j,繼續繪制
                    i = ii;
                    j = jj;
                    getOld = 1;
                }
                canvas.drawText(number.getTileString(i,j), i*width+x, j*height+y, numberPaint);
                numberIndex = numberIndex + 1 ;
                System.out.println("AAA0 繪制數字 number = " + number.getTileString(i,j) + " | i = " + i
                        + " | j = " + j);
                // 繪制進程中 遇到 不為空的數字 , 播放音效 并 延遲300毫秒
                System.out.println();
                if (number.getTileString(i,j) != "" && numberIndex<81){
                    mainActivity.playSound(); // 調用MainActivity里的方法,播放音效
                    handler.sendEmptyMessageDelayed(0, 1); // 等待300毫秒,給handler發消息
                    break outterLoop2;
                }
            }
        }



    }

    /**
     * 獲得按下的數字
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            selectedX = (int)(event.getX() / width);
            selectedY = (int)(event.getY() / height);

            StringBuffer sb = new StringBuffer();

            if (selectedY < 9){
                int used[] = number.getUsedTilesByCoor(selectedX,selectedY);
                for (int i = 0; i < used.length; i++) {
                    sb.append(used[i]);
                }
                //LayoutInflater layoutInflater = LayoutInflater.from(this.getContext());
                //View layoutView = layoutInflater.inflate(R.layout.dialog,null);
                //TextView textView = (TextView) layoutView.findViewById(R.id.usedTextId);
                //textView.setText("該位置不可用數字 = " + sb.toString());
                //AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
                //builder.setView(layoutView);
                //AlertDialog dialog = builder.create();
                //dialog.show();
                KeyDialog keyDialog = new KeyDialog(getContext(), used, this);
                keyDialog.show();
            }

            //Toast.makeText(getContext(), "ACTION_DOWN = " + used, Toast.LENGTH_SHORT).show();
            if (selectedY == 9){
                if (selectedX>=3 && selectedX<=5){
                    //Toast.makeText(getContext(), "ACTION_DOWN = 刷新",Toast.LENGTH_SHORT).show();
                    if (checkPoint == 1){
                        checkPoint = 2;
                    } else if (checkPoint == 2){
                        checkPoint = 1;
                    }
                    //Toast.makeText(getContext(), "checkPoint = " + checkPoint, Toast.LENGTH_SHORT).show();
                    number = new Number(checkPoint);
                    numberIndex = 0;
                    invalidate(); // onDraw()
                }
            }

        }
        return true;
    }

    private int numberIndex = 0; // 繪制完成的數字,下標81
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            invalidate(); // onDraw();
        }
    };

    // KeyDialog當按下1個數字,隱藏KeyDialog后,會調用下面這個方法,K4
    public void setSelectedTile(int tile) {
        System.out.println("BBB = selectedX = " + selectedX + " | selectedY = " + selectedY + " | tile = " + tile);
        if (number.setTileIfValid(selectedX, selectedY, tile)) { // 設置按下的數字到數組中,并判斷是不是為真,K5
            invalidate(); // onDraw(),K6
        }
    }
}
Number.java:
package com.iwanghang.newview;

public class Number {
    // 定義81個數字
    // str1、str2 各代表1個關卡
    private final String str1 = "600040800084005032000090700563180400009027000708604391" +
            "392476518150900200047512063";
    private final String str2 = "102004007000080000006000000050000380000000000000902000" +
            "000000070000000102089030000";

    // 實例化1個下標81的數組
    private int number[] = new int[9*9];

    // 存儲不可用數據
    private int used[][][] = new int[9][9][];

    public Number(){
        number = fromPuzzleString(str1);
    }

    public Number(int str){
        if (str == 1){
            number = fromPuzzleString(str1);
        }else if (str == 2){
            number = fromPuzzleString(str2);
        }
        calculateAllUsedTiles(); // 獲得當前關卡不可用數字數組
    }

    // 把81個數字設置到數組中,為0的設置為空
    private int[] fromPuzzleString(String str) {
        int[] number = new int[str.length()];
        for (int i = 0; i < number.length; i++) {
            number[i] = str.charAt(i) - '0';
        }
        return number;
    }

    // 根據數字在第幾行第幾個,獲得其在數組中的下表
    private int getTile(int x, int y){
        //return number[y * 9 + x];
        if (y * 9 + x < 81){
            return number[y * 9 + x];
        }else {
            return 0;
        }
    }

    // 獲得數字的字符串類型
    public String getTileString(int x, int y){
        int v = getTile(x,y);
        if (v == 0){
            return "";
        }else
            return String.valueOf(v);
    }






    public int[] getUsedTilesByCoor(int x,int y){
        return used[x][y];
    }

    public void calculateAllUsedTiles() {
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {
                used[x][y] = calculateUsedTiles(x, y);
            }
        }
    }

    /**
     * 獲得當前關卡不可用數字數組
     */
    public int[] calculateUsedTiles(int x, int y) {
        int c[] = new int[9];

        for (int i = 0; i < 9; i++) {
            if (i == y)
                continue;
            int t = getTile(x, i);
            if (t != 0)
                c[t - 1] = t;
        }

        for (int i = 0; i < 9; i++) {
            if (i == x)
                continue;
            int t = getTile(i, y);
            if (t != 0)
                c[t - 1] = t;
        }

        int startx = (x / 3) * 3;
        int starty = (y / 3) * 3;
        for (int i = startx; i < startx + 3; i++) {
            for (int j = starty; j < starty + 3; j++) {
                if (i == x && j == y)
                    continue;
                int t = getTile(i, j);
                if (t != 0)
                    c[t - 1] = t;
            }
        }
        // compress
        int nused = 0;
        for (int t : c) {
            if (t != 0)
                nused++;
        }
        int c1[] = new int[nused];
        nused = 0;
        for (int t : c) {
            if (t != 0)
                c1[nused++] = t;
        }
        return c1;
    }








    protected boolean setTileIfValid(int x, int y, int value) {
        System.out.println("Number BBB = x = " + x + " | y = " + y + " | value = " + value);
        int tiles[] = getUsedTiles(x, y);
        if (value != 0) {
            for (int tile : tiles) {
                if (tile == value)
                    return false;
            }
        }
        setTile(x, y, value);
        calculateAllUsedTiles();
        return true;
    }

    protected int[] getUsedTiles(int x, int y) {
        return used[x][y];
    }

    private void setTile(int x, int y, int value) {
        number[y * 9 + x] = value;
    }
}
MainActivity.java:
package com.iwanghang.newview;

import android.media.AudioManager;
import android.media.SoundPool;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    private SoundPool soundPool;
    private static int soundId;
    int resId = R.raw.doo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        //setContentView(R.layout.activity_main);

        NewView newView = new NewView(this);

        setContentView(newView);
        initSoundPool(resId);
    }

    public void initSoundPool(int resId) { // 初始化聲音池
        soundPool = new SoundPool(
                3, // maxStreams參數,該參數為設置同時能夠播放多少音效
                AudioManager.STREAM_MUSIC, // streamType參數,該參數設置音頻類型,在游戲中通常設置為:STREAM_MUSIC
                1 // srcQuality參數,該參數設置音頻文件的質量,目前還沒有效果,設置為0為默許值。
        );
        soundId = soundPool.load(this, resId, 1);
    }

    public void playSound() { // 播放聲音,參數sound是播放音效的id,參數number是播放音效的次數
        soundPool.play(
                soundId, // 播放的音樂id
                1, // 左聲道音量
                1, // 右聲道音量
                1, // 優先級,0為最低
                0, // 循環次數,0無不循環,⑴無永久循環
                1 // 回放速度 ,該值在0.5⑵.0之間,1為正常速度
        );
    }

    public void stopSound() { // 播放聲音,參數sound是播放音效的id,參數number是播放音效的次數
        if (soundPool != null && soundId > 0) {
            soundPool.stop(soundId);
            soundPool.release();
        }
    }

}
keypad.xml:
<?xml version="1.0" encoding="utf⑻"?>
<!--
 ! Excerpted from "Hello, Android!",
 ! published by The Pragmatic Bookshelf.
 ! Copyrights apply to this code. It may not be used to create training material,
 ! courses, books, articles, and the like. Contact us if you are in doubt.
 ! We make no guarantees that this code is fit for any purpose.
 ! Visit http://www.pragmaticprogrammer.com/titles/eband for more book information.
-->
<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keypad"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:stretchColumns="*">
    <TableRow>
        <Button android:id="@+id/keypad_1"
            android:text="1">
        </Button>
        <Button android:id="@+id/keypad_2"
            android:text="2">
        </Button>
        <Button android:id="@+id/keypad_3"
            android:text="3">
        </Button>
    </TableRow>
    <TableRow>
        <Button android:id="@+id/keypad_4"
            android:text="4">
        </Button>
        <Button android:id="@+id/keypad_5"
            android:text="5">
        </Button>
        <Button android:id="@+id/keypad_6"
            android:text="6">
        </Button>
    </TableRow>
    <TableRow>
        <Button android:id="@+id/keypad_7"
            android:text="7">
        </Button>
        <Button android:id="@+id/keypad_8"
            android:text="8">
        </Button>
        <Button android:id="@+id/keypad_9"
            android:text="9">
        </Button>
    </TableRow>
</TableLayout>



轉載請注明出處:http://blog.csdn.net/iwanghang/



歡迎移動開發愛好者交換
沈陽或周邊城市公司成心開發Android,請與我聯系
聯系方式

微信:iwanghang
QQ:413711276
郵箱:iwanghang@qq.com



覺得博文有用,請點贊,請評論,請關注,謝謝!~

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 日本高清中文字幕一区二区三区 | 一二三四视频免费观看在线看1 | 日韩久久网 | аⅴ中文在线天堂 | 亚洲天堂在线观看视频 | 精品日韩 | 精产国品一区 | 欧美视频在线免费 | 国产最新进精品视频 | 亚洲天堂免费在线 | www视频在线观看天堂 | 久久国产精品久久精 | 国产高清在线精品一区a | 国产精品久久久久久久免费大片 | 国产精品亚洲综合第一区 | 91午夜精品亚洲一区二区三区 | 男女男精品视频站 | 亚洲免费不卡 | 伊人久久久综在合线久久在播 | 久久永久免费视频 | 日韩 国产 欧美视频一区二区三区 | 亚洲日韩第一页 | 亚洲欧美久久 | 久久久久久久久久久9精品视频 | 国产精品夜色视频一级区 | 一级毛片在线完整免费观看 | 亚洲国产成人久久一区二区三区 | 一本综合久久国产二区 | 国产a级一级久久毛片 | 亚洲 欧美 日韩 综合 | 亚洲成人高清 | 波多野结衣一区2区3区 | 精品一区二区三区中文字幕 | 日本免费一区二区视频 | 欧美性在线播放 | 成人偷拍自拍 | 今天免费中文字幕视频 | 韩日一区二区 | 中文在线第一页 | 久久小视频 | 一级欧美在线的视频 |