Kotlin的Android开篇探究Activity(一)

作者: 阴天吃鱼 | 来源:发表于2020-05-09 14:47 被阅读0次

    上一篇文章对Kotlin常用的语法进行了学习,
    当前系列文章,将针对Android开发在Kotlin下的代码风格进行学习

    目录
    1.1 findviewById
    1.2 点击、吐司、菜单
    1.3 Intent跳转(显示、隐式、Action)
    1.4 Intent传递数据与返回
    1.5 companion object
    1.6 标准函数with、run、apply
    1.7 定义静态方法
    1.8 BaseActivity的简单封装

    • 1.1 findviewById

    布局有大量控件的时候,之前开发需要大量的findviewById。所以在java中为了规避可以使用黄油刀等系列的控件。在Kotlin中就不需要了,在布局设置的id,在页面可以直接使用,使用之前自动导入以下包
    import kotlinx.android.synthetic.main.activity_main.*

    • 1.2 点击、吐司、菜单

    1.2.1 随便声明一个控件

    <TextView
            android:id="@+id/tvBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    

    1.2.2单例一个吐司

    object ToastUtils {
    
        fun toast(content: Context, text: String) {
            Toast.makeText(content, text, Toast.LENGTH_SHORT).show()
        }
    }
    

    1.2.3菜单布局

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/add_item"
            android:title="add" />
        <item
            android:id="@+id/delete_item"
            android:title="delete" />
    </menu>
    

    1.2.4整合到一起的Activity页面

    
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            //点击
            tvBtn.setOnClickListener {
                //吐司
                ToastUtils.toast(this,"this is a toast")
                //跳转 xx::class.java
                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent)
            }
        }
    
        //菜单方法
        override fun onCreateOptionsMenu(menu: Menu?): Boolean {
            menuInflater.inflate(R.menu.menu_main_text, menu)
            return true
        }
    
        //菜单方法
        override fun onOptionsItemSelected(item: MenuItem): Boolean {
            when (item.itemId) {
                R.id.add_item -> ToastUtils.toast(this, "this is add item")
                R.id.delete_item -> ToastUtils.toast(this, "this is delete item")
            }
            return true
        }
    }
    
    • 1.3 Intent跳转(显示、隐式、Action)

                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent)
    
                val intent2 = Intent("com.hdsx.helloworld.ui.activity.second")
                intent2.addCategory("thisziyiding")
                startActivity(intent2)
    
                val intent3 = Intent(Intent.ACTION_VIEW)
                intent3.data = Uri.parse("https://www.baidu.com")
                startActivity(intent3)
    

    Activity ::class.java标记跳转class

    ** 第二个Activity的filter
    <activity android:name=".ui.activity.SecondActivity">
                <intent-filter>
                    <action android:name="com.hdsx.helloworld.ui.activity.second" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="thisziyiding"></category>
                </intent-filter>
            </activity>
    

    关于Intent.xxx不在多说,跟java以前一样,有兴趣的可自行扩展

    • 1.4 Intent传递数据与返回

    触发

    val intent = Intent(this, SecondActivity::class.java)
                intent.putExtra("value", "value")
                startActivityForResult(intent, 11)
    
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
            when (requestCode) {
                11 -> if (resultCode == Activity.RESULT_OK) {
                    val stringExtra = data?.getStringExtra("resultvalue")
                    tvBtn.setText(stringExtra)
                }
            }
        }
    

    接收返回

    class SecondActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_second)
    
            val stringExtra = intent.getStringExtra("value")
            tv_second.setText(stringExtra)
    
        }
    
        override fun onBackPressed() {
            val intent = Intent()
            intent.putExtra("resultvalue", "resultvalue")
            setResult(Activity.RESULT_OK, intent)
            finish()
        }
    }
    
    • 1.5 companion object

    在实际开发中,假设A页面和B页面分别是不同的同事开发,那A页面同事想要跳转到B页面的时候,会问B同事都要什么参数,或者说去看B页面同事的逻辑来确定参数。不管是哪种方法都会觉得很麻烦,在Kotlin中新加新的语法结构。companion object中的方法都可以使用类似于Java静态方法的形式调用,如下:

    B同事写法

    class SecondActivity : AppCompatActivity() {
    
        companion object {
            fun appStartSecondActivity(context: Context, resultvalue: String) {
                val intent = Intent(context, SecondActivity::class.java)
                intent.putExtra("value", resultvalue)
                context.startActivity(intent)
            }
        }
    }
    

    A同事调用

          SecondActivity.appStartSecondActivity(this, "resultvalue")
    

    不但简写了代码,还对B同事需要的参数一目了然。如果所有的Activity从最开始书写时都规定好,那良好的习惯能减少很多不必要的麻烦。

    • 1.6 标准函数with、run、apply

    1.6.1 with

    with(对象){ 对象的上下文环境}
    举例这个公式的含义,如下:

    先定义一个举例环境,

    val listOf = listOf<String>("orange", "apple", "pear")
        val stringBuilder = StringBuilder()
        stringBuilder.append("this start \n")
        for (value in listOf) {
            stringBuilder.append(value).append("\n")
        }
        stringBuilder.append("this end")
        val toString = stringBuilder.toString()
        println(toString)
    
    >log:
    this start 
    orange
    apple
    pear
    this end
    

    可见上述stringBuilder这个对象被多次调用。这种情况下可以考虑用with来精简代码

        val listOf = listOf<String>("orange", "apple", "pear")
        val with = with(StringBuilder()) {
            append("this start \n")
            for (value in listOf) {
                append(value).append("\n")
            }
            append("this end")
            toString()
        }
        println(with)
    
    >log:
    this start 
    orange
    apple
    pear
    this end
    

    可见上述with在花括号里 直接表示包裹对象的上下文环境,这就是with的作用

    1.6.2 run

    run跟with的函数意义差不多,但是不能像with直接使用,需要有提供对象,具体如下

        val listOf = listOf<String>("orange", "apple", "pear")
        val run = StringBuilder().run {
            append("this start \n")
            for (value in listOf) {
                append(value).append("\n")
            }
            append("this end")
            toString()
        }
        println(run)
    
    >log,
    this start 
    orange
    apple
    pear
    this end
    
    1.6.3 apply

    apply在功能跟上述都差不多,有区别的是,apply返回的是对象本身,而不是像run返回指定的类型。

    image.png
        val listOf = listOf<String>("orange", "apple", "pear")
        val apply = StringBuilder().apply {
            append("this start \n")
            for (value in listOf) {
                append(value).append("\n")
            }
            append("this end \n")
            toString()
        }
        println(apply.toString())
    
    >log
    this start 
    orange
    apple
    pear
    this end 
    this apply
    

    可以看图片,虽然在上下文环境中toString了,但实际apply的类型还是StringBuilder

    针对这个函数,我们可以对intent跳转进行优化,如下:

    companion object {
            fun appStartSecondActivity(context: Context, resultvalue: String) {
                val intent = Intent(context, SecondActivity::class.java).apply {
                    putExtra("value", resultvalue)
                    putExtra("value2", resultvalue)
                }
                context.startActivity(intent)
            }
        }
    
    • 1.7 定义静态方法

    之前上一章《Kotlin的语法学习之旅》知道了单例,通过单例我们也可以实现在Kotlin中全局调用,但加了object关键字会使得整个类的所有方法都是开放式的。 如果只是想其中某一个方法静态呢?可以使用本章( 1.5 companion object )如下:

    class Test {
        companion object {
            fun addStaticMethod() {
                println("this is jia de static")
            }
        }
    }
    

    这样就可以在全局调用,但实际这个关键词并不是真正的静态。如果工程是有java又有Kotlin的,在java代码中就调用不了。这种时候Kotlin也提供了方法

    class Test {
        companion object {
            @JvmStatic
            fun addStaticMethod() {
                println("this is jia de static")
            }
        }
    }
    

    @JvmStatic只能加在单例,或者被companion object修饰过得方法上,别的加了会报错。

    1.7.1 顶层方法

    除上述外,想全局使用还有一种就是顶层方法。顶层方法指的是 建立个xxx.kt文件,在kt文件里面书写的方法全都是全局可随意调用的。


    image.png
    image.png

    当然在Java中并没有什么顶层方法。但是Kotlin会自动根据这些创建一个一样的java类。在java中调用的话,就需要使用对象名 。 方法

    public class Test2 {
        public void Test2() {
            LettestKt.testString2();
        }
    }
    

    LettestKt是自动生成的。

    • 1.8 BaseActivity的简单封装

    没写别的,就写了添加activity和移除activity,用目前所学为基准

    1.8.1封装添加删除
    import android.app.Activity
    
    object ActivityCollector {
    
        private val arrayList = ArrayList<Activity>()
    
        fun addActivity(activity: Activity) {
            arrayList.add(activity)
        }
    
        fun removeActivity(activity: Activity) {
            arrayList.remove(activity)
        }
    
        fun cleadAllActivity() {
            for (activity in arrayList) {
                if (!activity.isFinishing) {
                    activity.finish()
                }
            }
            arrayList.clear()
        }
    }
    
    1.8.2创建BaseActivity
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import com.hdsx.helloworld.ui.utils.ActivityCollector
    
    open class BaseActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            ActivityCollector.addActivity(this)
        }
    
        override fun onDestroy() {
            super.onDestroy()
            ActivityCollector.removeActivity(this)
        }
    }
    
    

    加open关键字,表示当前类可被继承

    1.8.3 别的类继承
    class MainActivity : BaseActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
      }
    }
    

    : 可以表示继承,也可以表示接口

    总结:
    别的都不说,省略findviewById还是挺爽的,
    在代码上确实很精简,目前学到的Activity相关的跟Java在一些特性上还是大同小异的。

    相关文章

      网友评论

        本文标题:Kotlin的Android开篇探究Activity(一)

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