美文网首页kotlin小白日记
kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

作者: 唐_夏影 | 来源:发表于2018-09-16 18:48 被阅读54次

Kotlin初体验二「kotlin框架Anko的使用,工具类的封装,空值处理」

本篇上篇为kotlin初体验,源代码已上传至Github仓库的KotlinPractice2文件夹内

AndroidStudio是可以直接运行Main主函数类的,创建test包,在包下创建dmeo1.kt文件,输入以下代码

/**
 * 输入main提示输出主函数
 * 输入sout输出println
 */
fun main(args: Array<String>) {
    println("你好,世界")
}

右键Run就可以运行主函数中的代码了

AndroidStudio运行单个类.gif

页面布局

创建项目,在activity_main.xml下添加4个按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnLog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="封装Log" />

    <Button
        android:id="@+id/btnToasts"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="短吐司"
        />

    <Button
        android:id="@+id/btnToastL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="长吐司"
        />

    <Button
        android:id="@+id/btnNet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取网络数据"
        />

</LinearLayout>

添加按钮的点击事件

package com.example.tonjies.kotlinpractice2

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
//有了这一行后就不需要再写findById了
import kotlinx.android.synthetic.main.activity_main.*
//实现OnClickListener点击事件接口
class MainActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //初始化按钮
        init()
    }

    //初始化按钮
    private fun init() {
        btnLog.setOnClickListener(this)
        btnToasts.setOnClickListener(this)
        btnToastL.setOnClickListener(this)
        btnNet.setOnClickListener(this)
    }

    //实现按钮的点击事件
    override fun onClick(v: View?) {
        when (v?.id) {
            //使用封装的工具类打印Log
            R.id.btnLog -> {
                
            }
            //使用Anko框架输出短吐司
            R.id.btnToasts -> {

            }
            //使用Anko框架数据长吐司
            R.id.btnToastL -> {

            }
            //获取网络数据
            R.id.btnNet -> {

            }
        }
    }

}

工具类的封装

为什么要封装Log,这是因为我们每次输入Log的时候,每次都要重复的输入TAG,我们可以把Log封装成一个工具类,把固定的TAG变量抽取出来

在Kotlin中可以将类的关键字class替换成object,这样该类就会变成了一个单例模式的类,之后我们就可以接用使用类名.方法()的形式调用该类中的方法了

/**
 * 在kotlin中,加了object后,L类就成为了一个单例模式的类,相当于帮我们省略掉了以前Java实现单例的代码
 * 最后我们可以直接L.d调用类中的方法
 */
object L {
    //过滤词
    val TAG:String="tonjies"
    //5个等级 DIWE

    fun d(text: String) {
        Log.d(TAG, text + "")
    }
}

在Log按钮的点击事件里面使用

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.btnLog -> {
            //加了object关键字后成为了单例模式的类,直接类名.方法调用即可
            L.d("你好,世界")
        }
        R.id.btnToasts -> {

        }
        R.id.btnToastL -> {

        }
        R.id.btnNet -> {

        }
    }
}

点击按钮之后日志成功打印

打印Log.png

AnKo的吐司封装

这里介绍AnKo封装的吐司函数,在build.gradle加入依赖,点击同步

 compile "org.jetbrains.anko:anko-commons:0.10.5"

在按钮点击事件里面写入Anko框架里的toast短吐司,longToast长吐司函数

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.btnLog -> {
            //加了object关键字后成为了单例模式的类,直接类名.方法调用即可
            L.d("你好,世界")
        }
        R.id.btnToasts -> {
            toast("短吐司")
        }
        R.id.btnToastL -> {
            longToast("长吐司")
        }
        R.id.btnNet -> {

        }
    }
}

点击运行程序,查看短吐司和长吐司时候打印成功

空值处理

上一小节频繁出现了!和 ?两个符号,这两个符号在kotlin中代表的是空值处理。

什么意思呢,我们知道,在我们之前使用java的过程中,很容易就出现了NullPointerException异常。

举个例子,我们创建一个java学生类

//举个例子
public class Student {
    public void study() {
        System.out.println("学生在学习");
    }
}

测试Main函数

public class Demo {
    private static Student student;
    public static void main(String[] args) {
        student.study();
    }
}

我们声明了Student对象,但是却忘记new实例化它,之后就直接调用了学生的study方法,运行结果就是空指针异常了。

kotlin对这种现象进行了一些处理,现在我们创建test1.kt,创建主函数,同样声明我们的student(kotlin和java的类可以互调),不实现它。

fun main(args: Array<String>) {
    //报错
    var student: Student= null
}

我们发现程序直接报错了,这是因为我们的Kotlin默认时不允许你声明不实现的。但是有些情况,我们是没法提前实现的,比如要用后面的参数传递赋值

这个时候我们可以给该变量的类型加个?,表示允许该变量为空。

var student: Student?= null

我们再输出学生的学习方法,发现系统再次提示错误

空值处理.png

这是因为编译器检测到上面我们已经允许student值为空了,如果我们这时候不做任何处理,它仍然可能跑出空指针异常,所以编译器不允许我们做这么危险的事情。

移动到错误处,提示我们有两个操作符?.与!!可以操作,我们先使用?.。

//加入以后,即使是空值调用study方法也不会抛出空指针异常
student?.study()

我们发现报错消失,运行程序,虽然我们没有实例化Student类就调用了study方法,却没有任何错误,kotlin已经帮我们处理了这个问题,空指针问题解决(因为没有实例化student变量,当然也没有任何输出)。

那!!又是什么意思,它其实是一个比较作死的符号,如果我们使用它,就表示告诉编译器,我们不需要kotlin来帮我处理空指针异常了,你跟我像java一样运行就可以了。

//加入以后,编译器就不会再帮我们处理空指针异常了
student!!.study()

运行程序,结果果然崩溃了,出现了KotlinNullPointerException异常。所以该符号应该尽量少的使用。

除了上面的两个操作符外,kotlin还有一个叫做Elvis的 操作符供我们使用。

//加入之后,如果变量不为空,则执行变量的方法,如果变量为空,则执行右边的操作
student?.study() ?: pritln()
//声明在主函数之外
fun pritln() {
    println("变量为空")
}

这其实有点类似我们用if去做判断。

if(student==null){
    print("变量为空啦")
}else{
    student.study()
}

没错,正是我们java中对空值进行处理的方式。

完整代码。

fun main(args: Array<String>) {
    //报错
    var student: Student? = null
    //加入以后,即使是空值调用方法也不会抛出空指针异常
//    student?.study()
    //加入以后,编译器就不会再帮我们处理空指针异常了
//    student!!.study()
    //加入之后,如果变量不为空,则执行变量的方法,如果变量为空,则执行右边的操作
    student?.study() ?: pritln()
    if(student==null){
        print("变量为空啦")
    }else{
        student.study()
    }
}
//声明在主函数之外
fun pritln() {
    println("变量为空")
}

本小节就先到这里啦,如果文章对你有帮助,麻烦点个喜欢 or 关注,谢谢(っ╹◡╹)ノ。

相关文章

网友评论

    本文标题:kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

    本文链接:https://www.haomeiwen.com/subject/kiyfnftx.html