Android kotlin5分钟入门 快速掌握

问题
1.自动生成类名
2.自动生成get和set方法
 
该demo是使用Kotlin写的登录demo,使用MVP模式,里面用到了Retrofit+RxJava
 
学习的地址:
https://www.runoob.com/kotlin/kotlin-tutorial.html
 
 
非常好的学习的地方
https://www.kaops.com/iv/290
 
Kotlin不具备的特点:
静态成员
通配符类
非私有域
非检查型异常
原始类型
三元运算符a?b:c
 
生成
 
学习内容:
1.Kotlin的类怎么写
2.Kotlin的findview和属性设置
3.Kotlin绑定事件
4.在RecycleView里面的运用
5.生成get和set方法,不能自动生成
package kk.yuedong.com.myapplication

class TestBean {


    private var height = 0

    private var weight = 0


    fun getHeight(): Int {
        return height
    }

    fun setHeight(height: Int) {

        this.height = height;
    }
}
在Kotlin中,getter和setter是可选的,如果你没有在代码中创建它们,它是会默认自动生成,是看不到的:

class Account {
    var name: String = ""
    var age: Int = 0
    var balance: Double = 0.0
}
以上的代码,就算不写getter/setter,默认也会生成getter和setter,例如:

复制代码
class Account {
    var name: String = ""
    var age: Int = 0
    var balance: Double = 0.0

    // 这种set和get方法不推荐在代码中自己手动去写
        set(vaule){
            field = value
        }
        get() = field
}
Kotlin的成员变量无法被Java子类使用的问题
 

解决方法

abstract class Test{
    @JvmField
    protected var TAG: String
}
 
6.toString生成,$符号
override fun toString(): String {
    return "TestBean(height=$height, weight=$weight)"
}
7.类的实例化
var testBean=TestBean();
var height=testBean.getHeight();
8.静态变量和静态方法

Kotlin中常量和静态方法

class StaticDemoActivity {
    public static final String LOAN_TYPE = "loanType";
    public static final String LOAN_TITLE = "loanTitle";
}
class StaticDemoActivity {
    companion object {
        val  LOAN_TYPE = "loanType"
        val  LOAN_TITLE = "loanTitle"
    }
}

或者

class StaticDemoActivity {
    companion object StaticParams{
        val  LOAN_TYPE = "loanType"
        val  LOAN_TITLE = "loanTitle"
    }
}

或者
class StaticDemoActivity {
    companion object {
        const val LOAN_TYPE = "loanType"
        const val LOAN_TITLE = "loanTitle"
    }
}

静态方法

Java代码:

class StaticDemoActivity {
    public static void test(){
        、、、
    }
}

Kotlin中

class StaticDemoActivity {
    companion object {
        fun test(){
            、、、
        }
    }
}

或者

class StaticDemoActivity {
    companion object StaticParams{
        fun test() {
            、、、
        }
    }
}
非空属性必须在定义的时候初始化,kotlin提供了一种可以延迟初始化的方案,使用 lateinit 关键字描述属性:
public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}
Kotlin的构造函数直接声明在类的后面,并且变量的声明也可以在函数的参数中声明,最后字符串的输出,直接使用${变量名}的形式输出
var testBean=TestBean();
var height=testBean.getHeight();
Log.d("peng","height="+height);
println("$height start paly")
 

Kotlin中使用JNI

Kotlin和Rxjava+mvp+Retrofit的用法

kotlin使用Dagger2

kotlin实用反射

 
 
 
1 说一下Kotlin的伴生对象(关键字companion使用要说出来)
 
2 Kotlin的高阶函数使用过吗(平时使用的map,let ,apply ,also之类的都是高阶函数)
 
(这些问题都可以在我的Kotlin专栏里面找到,)
 
3 java 中定义了一个静态的变量
 
例如 final static int A = 10 在Kotlin 中 怎样 实现 (其实这个也是说伴生对象,)
 

Kotlin定义静态变量、静态方法

kotlin定义静态变量、方法可以采用伴生对象companion object的方式。 
经典例子,实例化Fragment。 

 
0.在建项目的时候,添加kotlin依赖,生成项目的时候会自带
 
1.依赖关系
我们会增加Kotlin标准库,Anko库,以及Kotlin和Kotlin Android Extensions plugin插件到dependencies。

3.把MainActivity转换成Kotlin代码

        Kotlin plugin包含了一个有趣的特性,它能把Java代码转成Kotlin代码。正如任何自动化那样,结果不会很完美,但是在你第一天能够使用Kotlin语言开始编写代码之前,它还是提供了很多的帮助。

        所以我们在MainActivity.java类中使用它。打开文件,然后选择Code -> Convert Java File to Kotlin File。对比它们的不同之处,可以让你更熟悉这门语言。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
 
控件的属性使用
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin)

        //实例化控件
        var tv = findViewById<TextView>(R.id.tv)
        var btn = findViewById<Button>(R.id.btn)

        //为TextView设置文字
        //tv.setText("这是一个kotlin编写的activity")
        tv.text = "这是一个kotlin编写的activity"

        //为按钮设置点击事件
        //直接使用lambda表达式,如果不需要参数,直接省略
        btn.setOnClickListener { Toast.makeText(this@KotlinActivity, "点击按钮", Toast.LENGTH_SHORT).show() }
    }
在输入setText方法时,IDE会给我们提示。
 

监听器

为按钮设置点击事件时,IDE会自动提示使用lambda表达式。
一般看到带有->箭头的标志就代表是lambda表达式。

//为按钮设置点击事件
        //直接使用lambda表达式,如果不需要参数,直接省略
        btn.setOnClickListener { Toast.makeText(this@KotlinActivity, "点击按钮", Toast.LENGTH_SHORT).show() }
 
小例子:
class MainActivity : AppCompatActivity() {

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

        var tv_test=findViewById(R.id.peng_tv)
        tv_test.text="871"


        tv_test.setOnClickListener {

            tv_test.text="pengpeng"
        }


    }
}
Kotlin的可见修饰符与Java类似,但是默认的可见性不一样,如果省略修饰符:Java默认包私有,Kotlin默认声明是public
运用的例子
1.在RecycleView里面的运用
https://www.jianshu.com/p/f01f63cb95f3
RecycleView需要添加manger
 
区间:
用于for循环

区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。 

区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。以下是使用区间的一些示例:


    var recyclerView=findViewById(R.id.recycler_view);

    recyclerView.layoutManager = LinearLayoutManager(this)
    var adapter=MyAdapter(this,initData()!!);

    recyclerView.adapter=adapter;

}

private fun initData(): ArrayList? {
    var list=ArrayList()
    for (i in 0..50){
        list.add(""+i);
    }
    Log.d("tag","list.size------"+ list.size)
    return list
}
构造函数的写法:
constructor(view: View) : super(view) {
    name = view.findViewById(R.id.item_title_popup_tv) as TextView

}
constructor(context: Context, list: ArrayList) {
    this.context = context
    this.list = list
    notifyDataSetChanged()
}
Kotlin中,一个类中可以有一个主构造函数和多个次构造函数。主构造函数就是声明在类头的构造函数,次构造函数必须委托主构造函数,文字太枯燥,举几个例子就一目了然了。
  //这是没有省略所有关键字的类声明,当然如果没有可见性的修饰符(默认是public),可以省略看见性修饰符和constructor
    class Player public constructor(val name :String){

        //如果想在构造函数中定一些变量或者创建对象,可以直接在类体中定义,也可以在init{...}代码块中去定义
        val id = "111"

        init{
            println("$id 是在初始化的代码块中")
        }

        fun play(){
            println("$name start paly")
        }

        // 调用player("222").play()输出下面字符串:
        // 111 是在初始化的代码块中
        // 222 start paly
    }


    // 主构造函数和次构造函数并存
//初始化块中的代码实际上会成为主构造函数的一部分。委托给主构造函数会作为次构造函数的第一条语句,因此所有初始化块中的代码都会在次构造函数体之前执行。即使该类没有主构造函数,这种委托仍会隐式发生,并且仍会执行初始化块
    class Player(val name: String) {
        val id = "111"

        init {
            println("$id 是在初始化的代码块中")
        }

        constructor(gender: String, name: String) : this("123") {
            println("我是 $gender 性")
        }

        fun play() {
            println("$name start paly")
        }

    }
 

我们可以像使用普通函数那样使用构造函数创建类实例:

val site = Runoob() // Kotlin 中没有 new 关键字
Kotlin构造函数小结:
可以有一个主构造函数和多个次构造函数
可以只有主构造函数和次构造函数
主、次构造函数同事存在的时候,次构造函数必须直接或者间接的委托到住构造函数
没有声明主构构造函数,会自动生成一个无参数的主构造函数,这点与java一样。
在主构造函数中你可以设置默认的值。
————————————————
init方法的调用时机
init {
    
}

数据类

个人觉得Kotlin的数据类使用起来真的很方便,省去我们很多工作量(妈妈从此再也不担心我写数据类了~~)。

先用Java写一个数据类,方便我们后面做对比

 

public class User {
    private String id;
    private String name;
    private int gender;
    private String avatar;
    private int age;

    public User(String id) {
        this.id = id;
    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

我们再来看看Kotlin如果实现一个对象类

 

 


data class User(val id: String, var name: String = "", var gender: Int = 0, var avatar: String = "", var age: Int = 0)

 

 

 

字符串模板

$:

 

fun main(args: Array) {
    val s = "runoob"
    val str = "$s.length is ${s.length}" // 求值结果为 "runoob.length is 6"
    println(str)
}

 

 

 

抽象类

抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。

注意:无需对抽象类或抽象成员标注open注解。

open class Base {
    open fun f() {}
}

abstract class Derived : Base() {
    override abstract fun f()
}

嵌套类

 


class Outer {                  // 外部类
    private val bar: Int = 1
    class Nested {             // 嵌套类
        fun foo() = 2
    }
}

fun main(args: Array) {
    val demo = Outer.Nested().foo() // 调用格式:外部类.嵌套类.嵌套类方法/属性
    println(demo)    // == 2
}

 

内部类

内部类使用 inner 关键字来表示。

内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

class Outer {
    private val bar: Int = 1
    var v = "成员属性"
    /**嵌套内部类**/
    inner class Inner {
        fun foo() = bar  // 访问外部类成员
        fun innerTest() {
            var o = this@Outer //获取外部类的成员变量
            println("内部类可以引用外部类的成员,例如:" + o.v)
        }
    }
}

fun main(args: Array) {
    val demo = Outer().Inner().foo()
    println(demo) //   1
    val demo2 = Outer().Inner().innerTest()
    println(demo2)   // 内部类可以引用外部类的成员,例如:成员属性
}
为了消除歧义,要访问来自外部作用域的 this,我们使用this@label,其中 @label 是一个 代指 this 来源的标签。

匿名内部类

使用对象表达式来创建匿名内部类:

class Test {
    var v = "成员属性"

    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

/**
 * 定义接口
 */
interface TestInterFace {
    fun test()
}

fun main(args: Array) {
    var test = Test()

    /**
     * 采用对象表达式来创建接口对象,即匿名内部类的实例。
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

类的修饰符

类的修饰符包括 classModifier 和_accessModifier_:

  • classModifier: 类属性修饰符,标示类本身特性。
    abstract    // 抽象类  
    final       // 类不可继承,默认属性
    enum        // 枚举类
    open        // 类可继承,类默认是final的
    annotation  // 注解类    // 抽象类  
    final       // 类不可继承,默认属性
    enum        // 枚举类
    open        // 类可继承,类默认是final的
    annotation  // 注解类
  • accessModifier: 访问权限修饰符
    private    // 仅在同一个文件中可见
    protected  // 同一个文件中或子类可见
    public     // 所有调用的地方都可见
    internal   // 同一个模块中可见    // 仅在同一个文件中可见
    protected  // 同一个文件中或子类可见
    public     // 所有调用的地方都可见
    internal   // 同一个模块中可见
 
 
as关键字的用法

kotlin学习笔记: ? 和 ?. 和 ?: 和 as? 和 !!

https://blog.csdn.net/baidu_31093133/article/details/81434181
 
基本语法
override fun onBindViewHolder(p0: MyViewHolder?, p1: Int) {
    p0?.name!!.text = list?.get(p1)?.name
    p0.image.setImageResource(list?.get(p1)?.res!!)
}
不需要分号
for循环的写法
class MyAdapter : RecyclerView.Adapter{

    private var context: Context? = null
    private var list: ArrayList? = null

    constructor(context: Context, list: ArrayList) {
        this.context = context
        this.list = list
        notifyDataSetChanged()
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHold {
//        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        return MyViewHold(LayoutInflater.from(context).inflate(R.layout.item_title_popup, null))
    }


    override fun getItemCount(): Int {
//        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        return 50
    }

    override fun onBindViewHolder(holder: MyViewHold, position: Int) {
//        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        holder.name.text="peng"+position
    }


    class MyViewHold : RecyclerView.ViewHolder {

        constructor(view: View) : super(view) {
            name = view.findViewById(R.id.item_title_popup_tv) as TextView

        }

        var name: TextView

    }

}
多个点击事件
when代替switch
override fun onClick(v: View?) {
    when (v?.id) {
        R.id.login ->
            if (checkContent(true)) {
                dialog = SweetAlertDialog(this, SweetAlertDialog.PROGRESS_TYPE)
                        .setTitleText("正在登录...")
                dialog?.setCancelable(false)
                dialog?.show()
                loginPresenter?.login(username.text.toString(), password.text.toString())
            }
        R.id.register ->
            if (checkContent(false)) {
                dialog = SweetAlertDialog(this, SweetAlertDialog.PROGRESS_TYPE)
                        .setTitleText("正在注册...")
                dialog?.setCancelable(false)
                dialog?.show()
                loginPresenter?.register(username.text.toString(), password.text.toString(), email.text.toString())
            }
    }
}

在Kotlin中如何将String转换为Int?

在Kotlin中可使用toInt()方法将字符串值转换为整数或INT。 以下是示例用法:

2.

kotlin的报错

kotlin.NotImplementedError: An operation is not implemented: not implemented

 
高级的东西
1.函数扩展
2.static怎么弄
3.数据类与密封类
 
 
 
 
Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。
基础语法
public fun sum(a: Int, b: Int): Int = a + b   // public 方法则必须明确写出返回类型

可变长参数函数:和asyncTask的一样

函数的变长参数可以用 vararg 关键字进行标识:

fun vars(vararg v:Int){
    for(vt in v){
        print(vt)
    }
}

// 测试
fun main(args: Array<String>) {
    vars(1,2,3,4,5)  // 输出12345
}

定义常量与变量

可变变量定义:var 关键字

var <标识符> : <类型> = <初始化值>

不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)

val <标识符> : <类型> = <初始化值>

NULL检查机制

Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做空判断处理

//类型后面加?表示可为空
var age: String? = "23" 
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1


类型检测及自动类型转换我们可以使用 is 运算符检测一个表达式是否某类型的一个实例(类似于Java中的instanceof关键字)。

fun getStringLength(obj: Any): Int? {
  if (obj is String) {
    // 做过类型判断以后,obj会被系统自动转换为String类型
    return obj.length 
  }

  //在这里还有一种方法,与Java中instanceof不同,使用!is
  // if (obj !is String){
  //   // XXX
  // }

  // 这里的obj仍然是Any类型的引用
  return null
}

比较两个数字

Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。数字类型也一样,所以在比较两个数字的时候,就有比较数据大小和比较两个对象是否相同的区别了。

在 Kotlin 中,三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小。

fun main(args: Array) {
    val a: Int = 10000
    println(a === a) // true,值相等,对象地址相等

    //经过了装箱,创建了两个不同的对象
    val boxedA: Int? = a
    val anotherBoxedA: Int? = a

    //虽然经过了装箱,但是值是相等的,都是10000
    println(boxedA === anotherBoxedA) //  false,值相等,对象地址不一样
    println(boxedA == anotherBoxedA) // true,值相等
}

链式调用(类似Glide的模式)

Glide.with(context)
.load(url)
.error(icon)
.into(view);

 

Kotlin 数据类与密封类

 
Kotlin完整项目
android kotlin实战demo
https://www.jianshu.com/p/4672c831865a
 
实战项目:安卓巴士

 

 

你可能感兴趣的:(kotlin)