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

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

选择API版本

之后选择空的 Activity 就开场了。
选择空活动

系统默认给出一个界面。
我们不理他,因为,还计划着以后再继续在这个项目中万一增加其他小工具呢。
所以新建一个package,取名就用汉语拼音吧。CaiPiao
新建package

新建好的package

然后在这个 package 下新建一个空活动(Empty Activity)
新建空活动

下面,我们要做的第一件事,就是让第一个活动(MainActivity)被应用启动后,直接跳转到我们这个 CaiPiao 下的空活动来。
主活动和彩票的活动

打开 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。我就用这种了。


出号界面布局

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


界面设置完毕

下面就该填写这个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 准确的识别,才能有下面的效果。

标准的注释写法很重要,会让你很方便。

我们要写双色球的随机出号了
首先定义一个整数数组,先都赋值为 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 内的东西。
我们在这里实践了一下编码中对中文变量的支持。呵呵。


资源在这里

这下知道两个textview上的文字从哪里来的了

编译一下


我用真机编译

Screenshot_2017-11-21-01-22-33-332_com.cofox.mykt.cst.png

Screenshot_2017-11-21-01-22-42-531_com.cofox.mykt.cst.png

Screenshot_2017-11-21-01-22-48-955_com.cofox.mykt.cst.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容