Android开发-自定义View-AndroidStudio(二十六)数独(3)Dialog监听

来源:互联网 发布:mac的ctrl 编辑:程序博客网 时间:2024/05/08 19:41
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/54290001
觉得博文有用,请点赞,请评论,请关注,谢谢!~

项目下载:http://download.csdn.net/detail/iwanghang/9739493


老规矩,先上GIF动态图,看个效果,如果符合你的项目或者确定你要了解的内容,再往下看吧:

看一下代码里面的K1,K2,K3,K4,K5,K6,就可以了解函数运行的顺序,最后在看一下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;    // 构造函数的第二个参数当中保存着当前单元格已经使用过的数字    public KeyDialog(Context context, int [] used){        super(context);        this.used = used;    }    // 构造函数的第二个参数当中保存着当前单元格已经使用过的数字    public KeyDialog(Context context,int [] used,NewView newView){        super(context);        this.used = used;        this.newView = newView;    }    // 当一个Dialog第一次显示的时候,会调用其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对象,刷新整个九宫格显示的数据    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系统需要绘制一个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发消息//            }//        }        /**         * 绘制一个刷新文字         */        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发消息//            }//        }        /**         * 优先绘制上一次绘制过的数字         */        int numberIndexOld = 0;        int ii = 0;        int jj = 0;        if (numberIndex != 0){ // 首次绘制,没有上一次绘制过的数字,所以不进入这个方法            System.out.println("AAA 优先绘制上一次绘制过的数字 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 优先绘制上一次绘制过的数字 number = " + number.getTileString(i,j) + " | i = " + i                            + " | j = " + j + " | numberIndexOld = " + numberIndexOld);                    if (numberIndexOld == (numberIndex-1)){                        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){ // 继续上一次绘制的数字的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当按下一个数字,隐藏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 各代表一个关卡    private final String str1 = "600040800084005032000090700563180400009027000708604391" +            "392476518150900200047512063";    private final String str2 = "102004007000080000006000000050000380000000000000902000" +            "000000070000000102089030000";    // 实例化一个下标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无永远循环                1 // 回放速度 ,该值在0.5-2.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-8"?><!-- ! 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/article/details/54290001



欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式

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



觉得博文有用,请点赞,请评论,请关注,谢谢!~

1 0
原创粉丝点击