Android Kotlin语言学习第一课:基本知识

一:Kotlin的类的定义
(1)如果一个类容许被继承必须应用open关键字润饰

(2)抽象类默认是open润饰
抽象类简介 : 抽象类不能被实例化 , 在 class 关键字前应用 abstract 润饰 ;
抽象类 , 默认应用 open 关键字润饰 , 能够间接继承 ;
形象办法 , 默认应用 open 关键字润饰 , 能够间接 override 重写 ;

抽象类总结 :
① 申明 : 抽象类中应用 abstract 申明 ;
② 成员 : 抽象类中既能够定义失常属性和办法 , 又能够定义形象的属性和办法 ;
③ 继承 : 抽象类能够继承抽象类 , 抽象类也能够继承失常类 , 失常类能够继承抽象类 ;
④ 重写 : 抽象类中能够应用形象办法重写失常办法 , 也能够进行失常的办法重写 ;
⑤ 特色 : 形象办法只能定义在抽象类中 , 失常类中不能有形象办法 ;

/** * @author zhiqiangRuan * @ClassName * @Date  2022/6/8 */abstract class BaseActivity : AppCompatActivity() {    /**     * kotlin 容许一个类继承另一个类     * kotlin 所有的类都继承自Any类(Any 不是 java.lang.Object)     * Any类是所有类的超类,对于没有超类型申明的类是默认超类     * Kotlin规定一个类能够给继承,必须应用open关键字润饰     * */    /**     * 抽象类:关键字为abstract     *形象函数: abstract fun initView()     *形象属性:abstract var name:String */    /**     *变量能够定义为可变(var)和不可变(val)     * 常量定义:val相当于被final 润饰  var相当于可变非final润饰     *等价于Java:public static final String TAG=BaseActivity.class.getSimpleName()*/    //定义标记    val TAG: String = this.javaClass.simpleName    //初始化布局View    abstract fun initView()    //初始化数据    abstract fun initData()    //初始化获取布局id,带返回值的形象办法    abstract fun getLayoutId(): Int    /**     * 语法定义     * fun 办法名 (参数名 :参数类型):返回值类型{     *     * return 返回值     *     * }     *     * 无返回值能够应用Unit 代替返回值类型 ?代表可空     * Kotlin 是null平安的语言 Byte ,Short,Int ,Long型的变量都是不能承受null值,如果要存储null值须要应用Byte?,Short?,Int?,Long?     *     *  override fun onCreate(savedInstanceState: Bundle?) :Unit{     *     *  }     **/    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(getLayoutId())        initView()        initData()    }    override fun onDestroy() {        super.onDestroy()    }}

二:变量和函数
val(value的简写)用来申明一个不可变的变量,这种变量在初始赋值之后就再也不能从新赋值,对应Java中的final变量;
var(variable的简写)用来申明一个可变的变量,这种变量在初始赋值会后依然能够再被从新赋值,对应Java中的非final变量;

//ps:Kotlin每一行代码的结尾是不必加分号的。fun main(){    val a = 10    val isFailed: Boolean get() = i > 3//赋值操作, i为变量;    println("a = "+ a)}

Kotlin的类型推导机制:代码中应用val关键字定义了一个变量a,并将它赋值为10,这里a就会被主动推导成整型变量。
因为既然你要把一个整数赋值给a,那么a就只能是整型变量,而如果你要把一个字符串赋值给a,那么a就会被主动推导成字符串变量;

fun (function的简称)是定义函数的关键字,无论定义什么函数,都肯定要是用fun来申明;
fun 办法体(参数1:参数类型,参数2:参数类型):返回值类型{
return 返回值
}

 fun largerNumber(num1:Int,num2: Int):Int{        return max(num1,num2)    }//等价于fun largerNumber(num1:Int,num2: Int)=max(num1,num2) //这种是更简便写法,Kotlin的推导机制   

三:kotlin-android-extensions 插件援用报错问题
其实在Kotlin 1.4.20中,JetBrains废除了kotlin-android-extensions编译插件,转而倡议咱们应用ViewBinding


四:Kotlin TODO编译闪退问题

 override fun initData() {        TODO("Not yet implemented")    }
/** * @author zhiqiangRuan * @ClassName * @Date  2022/6/8 */class FirstActivity : BaseActivity(), View.OnClickListener {override val TAG:String=this.javaClass.simpleName    //kotlin 中容许所有的类都继承/**     *  lateinit 关键字     * 提早初始化     * 这个关键字通知编译器,我无奈申明的时候就初始化,然而我保障我在应用前肯定会初始化,你就别给我查看了。*/     * /**咱们应用非空定义会报错,无奈申明时候就晓得这个view是什么,应用空定义能够定义*/     //var tvTitle:TextView?=null    lateinit var tvTitle:TextView    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)    }    override fun initView() {        /**         * 第一种写法:         * findViewById写法,在泛型中指定该控件类型         *         * 第二种写法:去掉泛型在后面申明改控件的类型         * var tvTitle :TextView=findViewById(R.id.tv_title)         *         * 第三种不要findViewById的形式         * 第一步: 在dependencies中 classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"插件         *第二步:build.gradle(app下的)的dependencies中增加         * implementation "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"         * 第三步:         * build.gradle(app下的)的plugins中增加id 'kotlin-android-extensions'         * 第四步:         * 同步一下         *         *  tv_title.text="aaa" 间接就赋值了         *其实在Kotlin 1.4.20中,JetBrains废除了kotlin-android-extensions编译插件,转而倡议咱们应用ViewBinding         *  Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.         * */      tvTitle = findViewById<TextView>(R.id.tv_title)tvTitle.setOnClickListener(this)    }    override fun initData() {    }    override fun getLayoutId(): Int {        return R.layout.activity_first    }    fun largerNumber(num1:Int,num2: Int):Int{        return max(num1,num2)    }override fun onClick(v: View?) {        when (v?.id) {            R.id.tv_title -> {                Log.d(TAG,"我点击了")            }        }    }}

五:Kotlin findViewById是想给布局赋值,给一个textView设置文字
在理论的业务场景中,View永远不会为空,因为一个为空的View是没有意义的,然而,咱们却申明了一个能够为空的View,这样一看起来比拟矛盾,二会影响浏览性。

/**     *  lateinit 关键字     * 提早初始化     * 这个关键字通知编译器,我无奈申明的时候就初始化,然而我保障我在应用前肯定会初始化,你就别给我查看了。*/    /**在理论的业务场景中,View永远不会为空,因为一个为空的View是没有意义的,然而,咱们却申明了一个能够为空的View,这样一看起来比拟矛盾,二会影响浏览性。*/    /**咱们应用非空定义会报错,无奈申明时候就晓得这个view是什么,应用空定义能够定义*///    lateinit var tvTitle:TextView    var tvTitle:TextView?=null

六:OnClickListener监听
extends被 : 代替,implement被 , 代替

class MainActivity : AppCompatActivity() {    //提早初始化    lateinit var tvClick: TextView    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        tvClick = findViewById<TextView>(R.id.tv_click)        tvClick.setOnClickListener(object : View.OnClickListener {            override fun onClick(v: View?) {                //点击事件监听                //获取Intent 对象                val intent = Intent()                // 获取class是应用::反射(那么问题来了,反射是个什么鬼?小白的悲痛啊,连忙钻研钻研去                intent.setClass(this@MainActivity, FirstActivity::class.java)                startActivity(intent)            }        })    }}

第二种形式:

/** * @author zhiqiangRuan * @ClassName * @Date  2022/6/8 */class FirstActivity : BaseActivity(), View.OnClickListener {    override val TAG: String = this.javaClass.simpleName    //kotlin 中容许所有的类都继承    /**     *  lateinit 关键字     * 提早初始化     * 这个关键字通知编译器,我无奈申明的时候就初始化,然而我保障我在应用前肯定会初始化,你就别给我查看了。*/    /**在理论的业务场景中,View永远不会为空,因为一个为空的View是没有意义的,然而,咱们却申明了一个能够为空的View,这样一看起来比拟矛盾,二会影响浏览性。*/    /**咱们应用非空定义会报错,无奈申明时候就晓得这个view是什么,应用空定义能够定义*/    lateinit var tvTitle: TextView    lateinit var tvRecycler: RecyclerView    //    var tvTitle: TextView? = null    private var myAdapter: MyAdapter? = null    //初始化数据汇合    private var students= ArrayList<Student>()    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)    }    override fun initView() {        /**         * 第一种写法:         * findViewById写法,在泛型中指定该控件类型         *         * 第二种写法:去掉泛型在后面申明改控件的类型         * var tvTitle :TextView=findViewById(R.id.tv_title)         *         * 第三种不要findViewById的形式         * 第一步: 在dependencies中 classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"插件         *第二步:build.gradle(app下的)的dependencies中增加         * implementation "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"         * 第三步:         * build.gradle(app下的)的plugins中增加id 'kotlin-android-extensions'         * 第四步:         * 同步一下         *         *  tv_title.text="aaa" 间接就赋值了         *其实在Kotlin 1.4.20中,JetBrains废除了kotlin-android-extensions编译插件,转而倡议咱们应用ViewBinding         *  Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.         * */        tvTitle = findViewById<TextView>(R.id.tv_title)        tvRecycler = findViewById<RecyclerView>(R.id.tv_recycler)        //设置布局排列形式        val linearLayoutManager = LinearLayoutManager(this)        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL        tvRecycler.layoutManager = linearLayoutManager        //增加分割线        tvRecycler.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))        //加载适配器        myAdapter = MyAdapter(students)        //设置适配器        tvRecycler.adapter = myAdapter        tvTitle.setOnClickListener(this)    }    override fun initData() {        for (i in 0 until 50) {            val student=Student()            student.name=i.toString()+"同学"            student.age=i            students.add(student)        }    }    override fun getLayoutId(): Int {        return R.layout.activity_first    }    fun largerNumber(num1: Int, num2: Int): Int {        return max(num1, num2)    }    override fun onClick(v: View?) {        when (v?.id) {            R.id.tv_title -> {                Log.d(TAG, "我点击了")            }        }    }}

七:kotlin之构造函数(constructor)

java中的构造函数是与类名雷同即可,kotlin外面的构造函数是用constructor关键字示意。
kotlin外面的构造函数分为主构造函数和次构造函数。主构造函数只能有一个,次构造函数个数不限度,能够有一个或者多个

//主构造方法如下,跟在类名前面class Person constructor(name:String){    }class Person constructor(){    }//当主构造方法没有任何注解或者可见性修饰符时,能够省略,写成上面这样class Person {    }//这种就是有注解标记的主构造方法,不能省略class Person @Inject internal constructor(){    }//次构造方法,一个无参的次构造方法,一个有一个参数的次构造方法class Person {    constructor(){            }        constructor(name:String){            }}

八:Kotlin 适配器编写和数据bean

/** * @author zhiqiangRuan * @ClassName * @Date  2022/6/9 *//** * MyAdapter (val students:List<Student>) * 是一个主构造函数 * List<Student> 参数类型*/class MyAdapter(val students: List<Student>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {    /**     * inner 定义外部类     *     * class MyViewHolder(view: View)     * 主构造函数View     * 次构造函数 constructor     * */    inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {        val tvName: TextView = view.findViewById(R.id.tv_name)        val tvAge: TextView = view.findViewById(R.id.tv_age)    }    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {        val view = LayoutInflater.from(parent.context).inflate(R.layout.first_item, parent, false)        return MyViewHolder(view)    }    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {        val student = students[position]        holder.tvName.text = student.name        holder.tvAge.text = student.age.toString()    }    override fun getItemCount(): Int {        return students.size    }}

布局文件first_item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/tv_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:text="姓名" />        <TextView            android:id="@+id/tv_age"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:text="年纪" />    </RelativeLayout></LinearLayout>

Student数据bean

/** * @author zhiqiangRuan * @ClassName * @Date  2022/6/9 */class Student : Serializable {    var name: String? = null    var age: Int? = 0}

END:新常识学习会面对很多的坑,但也会发现很多美好