24. 简单玩玩kotlin for android,随机数字买彩票

现在 kotlin 用的较多的领域,应该是 android 应用开发了吧。最近开了个小差,有人买彩票不想自己预测了,也不想现场用彩票店的机器出号,太费事儿。就用 kotlin 写个手机 apk 给他。要求也不高,只要随机出数字就行。
需求搞清楚了,可以开工了。
首先要确定,他可能还要给自己的旧手机也装上,为求万千稳妥,API 的最小版本选择了 15。

24. 简单玩玩kotlin for android,随机数字买彩票_第1张图片
选择API版本

之后选择空的 Activity 就开场了。
24. 简单玩玩kotlin for android,随机数字买彩票_第2张图片
选择空活动

系统默认给出一个界面。
我们不理他,因为,还计划着以后再继续在这个项目中万一增加其他小工具呢。
所以新建一个package,取名就用汉语拼音吧。 CaiPiao
24. 简单玩玩kotlin for android,随机数字买彩票_第3张图片
新建package

24. 简单玩玩kotlin for android,随机数字买彩票_第4张图片
新建好的package

然后在这个 package 下新建一个空活动(Empty Activity)
24. 简单玩玩kotlin for android,随机数字买彩票_第5张图片
新建空活动

下面,我们要做的第一件事,就是让第一个活动(MainActivity)被应用启动后,直接跳转到我们这个 CaiPiao 下的空活动来。
24. 简单玩玩kotlin for android,随机数字买彩票_第6张图片
主活动和彩票的活动

打开 MainActivity ,添加代码。先写一个函数 OpenCaiPiao ,在函数内实现需要的功能。

    //跳转到彩票界面
    fun OpenCaiPiao(){//我要顺顺的来
        val intent = Intent()
        intent.setClass(this, CaipiaoActivity::class.java)
        startActivity(intent)
    }

把它放在 class MainActivity 内,并在 onCreate 函数内添加调用语句 OpenCaiPiao()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        OpenCaiPiao()

    }

这时候,我们的注意力就可以专注到真正的业务模块中了。
在 res>layout 中打开 activity_caipiao.xml,拖拽三个 button 和 两个 textview。
一个 button 对应“双色球”
一个 button 对应“大乐透”
一个 button 对应“清除”功能
一个 textview 对应给出的彩票号码
一个 textview 对应给出彩票号码的时间
现在流行最新的布局方式,也是默认的ConstraintLayout。我就用这种了。


24. 简单玩玩kotlin for android,随机数字买彩票_第7张图片
出号界面布局

这个布局中,为了保持“随机号码”和“出号时间”的左对齐,只设定了上边和左边的距离,它们字号不同,控制了右边距离的话,文字内容发生改变,会有对不齐的情况发生。
双色球和大乐透两个按钮,略有不同,双色球设置了上、左、右到边沿,而大乐透的左边是指在双色球按钮的右侧控键上。这样,两个按钮的位置就相对固定了。不论横屏还是竖屏都不会变。
相似的“清除按钮”的上边constraint也控制到双色球按钮的下侧控键上,这样“清除按钮”和“双色球按钮”的相对位置也就保持不变了。


24. 简单玩玩kotlin for android,随机数字买彩票_第8张图片
界面设置完毕

下面就该填写这个Activity中的代码了。
界面中可以直接操作就是这三个按钮了,先在 CaiPiaoActivity.kt 的 OnCreate 中增加这三个按钮的 OnClick 事件的监听。
        //双色球
        btnGetShuangSeQiu.setOnClickListener {
        }
        //大乐透
        btnDaLeTou.setOnClickListener {
        }
        //清除取消
        btnCancel.setOnClickListener {
        }

随机出彩票号码,那么核心功能是随机了。先写一个在指定的范围内出随机数字的函数出来。

/**
 * 取得min到max之间的随机整数(不包含max)
 * @min 最小取值
 * @max 最大取值边界(此值不取)
 * */
fun cofoxRandom(min: Int = 0, max: Int): Int {
    var t_min = min
    var t_max = max
    if (t_min > t_max) {
        var temp: Int
        temp = t_min
        t_min = t_max
        t_max = temp
    }
    var random = (Math.floor(Math.random() * (t_max - t_min))).toInt() + t_min

    return random
}

这里要注意这个注释的写法

/**
 *
 * */

这样标准的写法能够被 IDE 准确的识别,才能有下面的效果。

24. 简单玩玩kotlin for android,随机数字买彩票_第9张图片
标准的注释写法很重要,会让你很方便。

我们要写双色球的随机出号了
首先定义一个整数数组,先都赋值为 0 好了。

var ints = intArrayOf(0, 0, 0, 0, 0, 0, 0)

当然你也可以这样写

var ints = Array(7,{0})

第一种写法,是方便直接把所有的数组元素(不同值)都写进去。
第二种写法,更简洁一些,适合初始化时候都赋相同值的情况。
建立了数组,就该把随机数字填写进去了。

    for (i in 1..6) {
        ints[i - 1] = cofoxRandom(1, 34)
    }

双色球是 6 + 1 的出球方式。我们先出 6 个红球,所以是 1..6。
由于 cofoxRandom 函数的max值是不包含在可选范围内的,所以1-33个红球号码,我们需要的参数是(1, 34)
至于 ints[i-1],是因为,数组的下标是从 0 开始的。
这样就可以把 6 个球号得到了。
但是,还有个问题,数字是乱的。我们需要给这 6 个数字排序。这也是一个很常见的需求。

    //排序前六位,第七位当临时存储位
    for (i in ints.indices) {
        for (j in ints.indices - i) {
            if (j < ints.size - 1) {
                if (ints[j] > ints[j + 1]) {
                    ints[ints.size - 1] = ints[j + 1]
                    ints[j + 1] = ints[j]
                    ints[j] = ints[ints.size - 1]
                }
            }
        }
    }

这里,我们为了节省内存,就不再另外加变量了。先利用那个蓝色号码的位置,作为排序时的临时存储位。每次循环,都把较大的一个数字往后移动一位。于是,在第二层循环,每次循环都可以少循环一个已经确定了的较大数字。这就是

    for (i in ints.indices) {
        for (j in ints.indices - i) {

这个的来由。顺便说一下,indices是取得ints下标的意思。这样i和j就能得到当前循环的具体下标了。
循环完,一个由小到大排列好的数组就出来了。
如果想完美,还有一个问题要解决,重复数字。随机给出的数字经常是重复的。只要再加一个逻辑,当新的随机数出来后,判断一下在数组中是否存在这个数字了即可。如果存在,当前循环内再次取得随机数,直到取得了不在数组中的数字为止。
我们可以用 for 循环嵌套 while 循环实现。我们来修改刚才那个 随机数字填写 的 for 循环。

    for (i in 1..6) {
//        ints[i - 1] = cofoxRandom(1, 34)
        var temp = cofoxRandom(1, 34)
        while (temp in ints){
            temp = cofoxRandom(1, 34)
        }
        ints[i - 1] = temp
    }

现在,数组内的号码球数字不会重复了。
双色球还有一个蓝色号码求哦,这个就直接出好了。

ints[ints.size-1] = cofoxRandom(1, 17)//蓝色号码球

数字都出完了。我们还可以来调一调数字格式。因为,有一位数也有两位数嘛,排列总是看起来有点不够整齐。那就一位数的都在左侧补0吧。不仅如此,每个数字之间用逗号(,)分隔开,再把红球和蓝球用短横线(-)分隔开。

    //按格式书写
    var str = "双色球:"
    for (i in ints.indices) {
        if (ints[i].toString().length < 2){
            str += "0"+ints[i].toString()
        }else {
            str += ints[i]
        }

        if (i == ints.size-2){
            str += " - "
        }else if (i == ints.size -1){

        }else{
            str += ", "
        }
    }

好了。重要的代码都写完了。剩下就是把 str 赋值给界面控件了吧?
还可以再多做一点事情。不要把这么多的代码都放进 onCreate ,独立出一个函数来。让代码更整洁。于是,我们可以得到一个“福彩双色球随机猜想出号”函数了。

/**
 * 福彩双色球随机猜想出号
 * */
fun cofoxShuangSeQiu(ttvw:TextView){
//    var ints = intArrayOf(0, 0, 0, 0, 0, 0, 0)
    var ints = Array(7,{0})
    for (i in 1..6) {
//        ints[i - 1] = cofoxRandom(1, 34)
        var temp = cofoxRandom(1, 34)
        while (temp in ints){
            temp = cofoxRandom(1, 34)
        }
        ints[i - 1] = temp
    }
    //排序前六位,第七位当临时存储位
    for (i in ints.indices) {
        for (j in ints.indices - i) {
            if (j < ints.size - 1) {
                if (ints[j] > ints[j + 1]) {
                    ints[ints.size - 1] = ints[j + 1]
                    ints[j + 1] = ints[j]
                    ints[j] = ints[ints.size - 1]
                }
            }
        }
    }

    ints[ints.size-1] = cofoxRandom(1, 17)//蓝色号码球

    //按格式书写
    var str = "双色球:"
    for (i in ints.indices) {
        if (ints[i].toString().length < 2){
            str += "0"+ints[i].toString()
        }else {
            str += ints[i]
        }

        if (i == ints.size-2){
            str += " - "
        }else if (i == ints.size -1){

        }else{
            str += ", "
        }
    }
    ttvw.text = str
}

而 onCreate 中对这个函数进行调用。

cofoxShuangSeQiu(ttvwRandomNumber)

ttvwRandomNumber 就是 textview 的 id
在界面上为了更友好一些,我们增加了出号时间。现在就是添加这个功能代码的时候了。

/**
 * 显示当前出号时间
 * */
fun cofoxGetNumberTime(ttvw: TextView){
    //出号时间
    var ver = android.os.Build.VERSION.SDK_INT
    if (ver >= 24){
        ttvw.text = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())
    }else{
        val calendar = GregorianCalendar()
        ttvw.text = GregorianCalendar().get(Calendar.YEAR).toString() +"-"+ (GregorianCalendar().get(Calendar.MONTH)+1).toString() +"-"+ GregorianCalendar().get(Calendar.DAY_OF_MONTH).toString() +" "+ GregorianCalendar().get(Calendar.HOUR).toString() +":"+ GregorianCalendar().get(Calendar.MINUTE).toString() +":"+ GregorianCalendar().get(Calendar.SECOND).toString()
    }
}

好吧,这也是写成了一个函数。并且其中用了两种取得当前时间的方法。因为,我们开始的时候,希望这个应用能支持到 API 15,而最简洁最新的时间获取的写法是从 API 24 之后才开才是支持的。
那么先判断一下当前运行的 android 系统的 API 是哪个版本,然后对症下药。
之后,我们再把调用语句写入 onCreate 中。

        //双色球
        btnGetShuangSeQiu.setOnClickListener {
            cofoxShuangSeQiu(ttvwRandomNumber)
            cofoxGetNumberTime(ttvwTime)    //出号时间

        }

双色球的调用完成了。
大乐透只是稍有不同
大乐透的号码球一共也是 7 个,但是,大乐透的玩法是分前区和后区。是 5 + 2 的结构。所以,在双色球的代码基础上略微修改就可以获得大乐透的写法了。

/**
 * 体彩大乐透随机猜想出号
 * */
fun cofoxDaLeTou(ttvw:TextView){
//    var ints = intArrayOf(0, 0, 0, 0, 0, 0, 0)
    var ints = Array(7,{0})
    for (i in 1..5) {
//        ints[i - 1] = cofoxRandom(1, 36)
        var temp = cofoxRandom(1, 36)
        while (temp in ints){
            temp = cofoxRandom(1, 36)
        }
        ints[i - 1] = temp
    }

    //排序前5位,第6位当临时存储位
    for (i in ints.indices - 2) {
        for (j in ints.indices - i) {
            if (j < ints.size - 2) {
                if (ints[j] > ints[j + 1]) {
                    ints[ints.size - 2] = ints[j + 1]
                    ints[j + 1] = ints[j]
                    ints[j] = ints[ints.size - 2]
                }
            }
        }
    }

    ints[ints.size-2] = cofoxRandom(1, 13)//后区号码球1
    ints[ints.size-1] = cofoxRandom(1, 13)//后区号码球2

    //按格式书写
    var str = "大乐透:"
    for (i in ints.indices) {
        if (ints[i].toString().length < 2){
            str += "0"+ints[i].toString()
        }else {
            str += ints[i]
        }

        if (i == ints.size-3){
            str += " - "
        }else if (i == ints.size -1){

        }else{
            str += ", "
        }
    }
    ttvw.text = str
}

这时候,在 onCreate 中修改大乐透的调用代码就简单多了。

        //大乐透
        btnDaLeTou.setOnClickListener {
            cofoxDaLeTou(ttvwRandomNumber)
            cofoxGetNumberTime(ttvwTime)    //出号时间

        }

还记得我们的“清除”按钮吗?是的,也要在 onCreate 中写上监听代码。

        //清除取消
        btnCancel.setOnClickListener {
            ttvwRandomNumber.text = resources.getString(R.string.txt_cnword_随机号码)
            ttvwTime.text = resources.getText(R.string.txt_出号时间)
        }

这里的 R.string 是什么?它们资源文件 res>values 下 strings.xml 内的东西。
我们在这里实践了一下编码中对中文变量的支持。呵呵。


24. 简单玩玩kotlin for android,随机数字买彩票_第10张图片
资源在这里

24. 简单玩玩kotlin for android,随机数字买彩票_第11张图片
这下知道两个textview上的文字从哪里来的了

编译一下


24. 简单玩玩kotlin for android,随机数字买彩票_第12张图片
我用真机编译

24. 简单玩玩kotlin for android,随机数字买彩票_第13张图片
Screenshot_2017-11-21-01-22-33-332_com.cofox.mykt.cst.png

24. 简单玩玩kotlin for android,随机数字买彩票_第14张图片
Screenshot_2017-11-21-01-22-42-531_com.cofox.mykt.cst.png

24. 简单玩玩kotlin for android,随机数字买彩票_第15张图片
Screenshot_2017-11-21-01-22-48-955_com.cofox.mykt.cst.png

你可能感兴趣的:(24. 简单玩玩kotlin for android,随机数字买彩票)