十、kotlin综合笔记

br/>

1. kotlin的 apply使用:

有如下Kotlin代码

1
2
var intent = getInitIntent(readableMap)
intent.setClassName(currentActivity, readableMap.getString("entry"))

在kotlin中又更好实现方式:

1
2
3
4
5
6
7
	var intent = getInitIntent(readableMap).apply {
setClassName(currentActivity, readableMap.getString("entry"))
}
```
虽然从代码量看都是2行。但后者是将定义及赋值统一为一条语句来实现。

### 2. java中判断字符串值是否相等使用的是equals, 而在kotlin中进行了简化。使用 == 即可。

if ("action".equals(key)) {//java写法,kotlin中不推荐
    intent.setAction(readableMap.getString(key))
}
//kotlin中判断两个字符串是否相等跟比较int等number类型一样简单方便
if ("action" == key) {
    intent.action = readableMap.getString(key)
}
1
### 3. kotlin文件IO提供了很多有用方法。比如要迭代删除文件及子目录下文件夹及文件:
var file = File(BaseApplication.getInstance().filesDir, "rn")
file.deleteRecursively()
1
2
3
4
5
6

### 4. lateinit关键字使用
使用kotlin初期,我在声明类的属性变量时总是采用如下定义方式:

private var versionRepo : VersionRepo? = null
要使用该变量 versionRepo时,总是得要加 ? 或者 !! 比如:

private fun initUpgrade() {
versionRepo = VersionRepo(versionViewModel)
lifecycle.addObserver(versionRepo!!)
}

1
所有要使用 versionRepo 变量地方都要加上讨厌的 ? 或者 !! 这就是 lateinit 关键字使用好处之一了:

private lateinit var versionRepo: VersionRepo
初始化后再使用 versionRepo变量都不用再加 ?或者 !!

1
2
3
### 5.  函数只有一条返回语句的简写

getName方法原来是这么写的

class RnIntentModule(reactContext : ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {

override fun getName(): String {
    return "RnIntent"
}

}

1
现在可以一行简写:

class RnIntentModule(reactContext : ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {

override fun getName() = "RnIntent"

}

1
2
3
4

### 6. 函数参数带默认值

NotificationUtils.kt

fun buildPushNotification(context: Context, notification: com.govnet.im.main.notification.Notification, intent: Intent): Notification {
return buildPushNotification(context, notification.getNotificationMessage(context), intent)
}

public fun buildPushNotification(context: Context, msg: String, intent: Intent, vibrate: Boolean = false): Notification {
    val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    val builder = NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID)
            .setWhen(System.currentTimeMillis())
            .setContentTitle(defaultTitle)
            .setContentText(msg)
            .setSmallIcon(defaultIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

    if (vibrate) {
        builder.setVibrate(longArrayOf(0, 1000, 0, 0))
    }
    return builder.build()
}
1
2
3

### 7. 回调函数作为函数参数的写法
DateTimePickDialog.java

public class DateTimePickDialog {

private Activity activity;

public DateTimePickDialog(Activity activity) {
    this.activity = activity;
}
public void dateTimePickDialog(final TextView inputDate, final String formatStr, final OnDateTimeSelectClickListener listener) {
    new AlertDialog.Builder(activity)
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        if (onDateTimeSelectClickListener != null) {
                                            onDateTimeSelectClickListener.onDateTimeSelectClick();
                                        }
                                    }
                                })
                                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                    }
                                }).show();
}
public interface OnDateTimeSelectClickListener {
    void onDateTimeSelectClick();
}

}

1
在 OnMapSearchPopupWindow.kt 中调用 dateTimePickDialog 方法

class OnMapSearchPopupWindow(var context: Context) : PopupWindow() {
var onDateTimePickListener: ((Boolean, String) -> Unit)? = null

private fun selectTime() {
    val dialog = DateTimePickDialog(this)

    //写法一(不推荐)
    dialog.dateTimePickDialog(editor.editText, resFormat, object: DateTimePickDialog.OnDateTimeSelectClickListener{
        override fun onDateTimeSelectClick() {
            onDateTimePickListener?.invoke(isStartTime, editor.editText.text.toString())
        }
    })

    //写法二
    dialog.dateTimePickDialog(editor.editText, resFormat, {
        onDateTimePickListener?.invoke(isStartTime, editor.editText.text.toString())
    })

    写法二在as会有个黄色波浪线的代码提示:Move lambda arguments out of parenthesis , 按代码提示后写法变为:
    //写法三
    dialog.dateTimePickDialog(editor.editText){
        onDateTimePickListener?.invoke(isStartTime, editor.editText.text.toString())
    }
}

}

1
2

MainActivity.kt中 初始化 onDateTimePickListener

class MainActivity : Activity() {

private var mOnMapSearchPopupWindow: OnMapSearchPopupWindow? = null

override fun onCreate(savedInstanceState: Bundle?) {

    mOnMapSearchPopupWindow = OnMapSearchPopupWindow(this)
    mOnMapSearchPopupWindow?.onDateTimePickListener = { isStartTime, dateTime ->
                if (isStartTime) {
                    mQueryPersonTypeReq.startTime = dateTime
                } else {
                    mQueryPersonTypeReq.endTime = dateTime
                }
                mOnMapPresenter.queryPersonType(mQueryPersonTypeReq)
            }
}

}

1
2
3

### 8. kotlin中对于include子布局文件后的id引用:
activity_main.xml

<include android:id="@+id/toolBarInclude"
    layout="@layout/base_toolbar"/>


1
base_toolbar.xml

<?xml version=”1.0” encoding=”utf-8”?>

<android.support.v7.widget.Toolbar xmlns:android=”http://schemas.android.com/apk/res/android"
xmlns:app=”http://schemas.android.com/apk/res-auto"
android:id=”@+id/toolBar”
android:layout_width=”match_parent”
android:layout_height=”42dp”
android:background=”@color/color_theme”
app:popupTheme=”@style/ThemeOverlay.AppCompat.Light”
app:subtitleTextAppearance=”@style/baseToolbarSubTitle”
app:theme=”@style/ThemeOverlay.AppCompat.Dark.ActionBar”
app:titleTextAppearance=”@style/baseToolbarTitle”>
</android.support.v7.widget.Toolbar>

1
MainActivity如何使用ToolBar这个控件呢?

import kotlinx.android.synthetic.main.activity_main.*

private fun initToolbar() {

val myToolBar = (toolBarInclude as Toolbar)
myToolBar.title = getString(R.string.call_meeting_title)
myToolBar.setNavigationIcon(R.drawable.base_ic_arrow_toolbar)
myToolBar.setNavigationOnClickListener {
    finish()
}

}

1
2
3
debug下程序就知道 toolBarInclude 就是个Toolbar对象,所以强转他就可以使用了

### 9. if语句判断变量为空就return java代码写法:

MXSession session = Matrix.getInstance(context).getDefaultSession();
if(session == null){
return;
}

1
有4行代码,而用kotlin一行代码即可搞定:

val session = Matrix.getInstance(context).defaultSession ?: return
`