文章目录
List 增删改
fun <T> List<T>.upsert(value: T, finder: (T) -> Boolean) = indexOfFirst(finder).let { index ->
if (index >= 0) copy(index, value) else this + value
}
fun <T> List<T>.copy(i: Int, value: T): List<T> = toMutableList().apply { set(i, value) }
inline fun <T> List<T>.delete(filter: (T) -> Boolean): List<T> = toMutableList().apply { removeAt(indexOfFirst(filter)) }
Kotlin 带参回调
fun withState(block: (state: S) -> Unit) {
block.invoke(state)
//block(state)
}
// 调用
withState { state->
}
kotlin操作符重载
class Test {
/**
* Can be invoked as an operator like: `yourProp()`
*/
open operator fun invoke(): String? = null
}
调用
Test().invoke()?:"MaQi"
Test()()?:"MaQi"
当然也可以被重写
class Son : Test() {
override fun invoke(): String = "Son"
}
data copy函数
data class User(val name:String)
User("").copy(name = "马齐")
Array joinToString 扩展
private fun demonstrates(vararg items: String) =
arrayOf("Demonstrates:", *items).joinToString("\n\t\t• ")
navigateTo 函数
protected fun navigateTo(@IdRes actionId: Int, arg: Parcelable? = null) {
val bundle = arg?.let { Bundle().apply { putParcelable("KEY_ARG", it) } }
findNavController().navigate(actionId, bundle)
}
Fragment.kt 扩展函数
fun Fragment.findNavController(): NavController =
NavHostFragment.findNavController(this)
Unit 无返回调用
override fun onOptionsItemSelected(item: MenuItem?) = when (item?.itemId ?: 0) {
R.id.menu_refresh -> viewModel.refreshTasks().andTrue()
R.id.menu_filter -> showFilteringPopUpMenu().andTrue()
R.id.menu_clear -> viewModel.clearCompletedTasks().andTrue()
else -> super.onOptionsItemSelected(item)
}
/**
// 翻译:Unit相当于Java的Void类型
* The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
*/
@Suppress("Detekt.FunctionOnlyReturningConstant")
private fun Unit.andTrue() = true
反编译Java代码
public boolean onOptionsItemSelected(@Nullable MenuItem item) {
boolean andTrue;
switch (item != null ? item.getItemId() : 0) {
case R.id.menu_clear:
getViewModel().clearCompletedTasks();
andTrue = andTrue(Unit.INSTANCE);
break;
case R.id.menu_filter:
showFilteringPopUpMenu();
andTrue = andTrue(Unit.INSTANCE);
break;
case R.id.menu_refresh:
getViewModel().refreshTasks();
andTrue = andTrue(Unit.INSTANCE);
break;
default:
andTrue = super.onOptionsItemSelected(item);
break;
}
return andTrue;
}
private final boolean andTrue(@NotNull Unit $receiver) {
return true;
}
可以发现Java中完全无关的两个函数被Kotllin巧妙的关联起来
PopupMenu ToolBar点击弹窗
//使用方法
PopupMenu(requireContext(), requireActivity().findViewById<View>(R.id.menu_filter)).run {
menuInflater.inflate(R.menu.filter_tasks, menu)
setOnMenuItemClickListener { item ->
//doSomething
true
}
show()
}
//menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_filter"
android:title="@string/xxx"
android:icon="@drawable/xxx"
app:showAsAction="always" />
</menu>
//填充Menu
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater?.inflate(R.menu.tasks_fragment_menu, menu)
}
JvmOverloads 优化自定义View构造函数
class FullScreenMessageView : FrameLayout {
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr) {
inflate(context, R.layout.full_screen_message, this)
}
}
get()= ,get() , =的区别
// 1
private val navController: NavController
get() = findNavController(R.id.nav_host)
// 2
private val navController: NavController
get() {
return findNavController(R.id.nav_host)
}
// 3
private val navController = findNavController(R.id.nav_host)
Java代码
// 1
private final NavController getNavController() {
return ActivityKt.findNavController(this, R.id.nav_host);
}
//2
private final NavController getNavController() {
return ActivityKt.findNavController(this, R.id.nav_host);
}
// 3
private final NavController navController = ActivityKt.findNavController(this, R.id.nav_host);
可以发现
1.get()= 和get()没区别
2.get() 和 = 加载时机不同
typealias 别名的使用
申明
//Tasks.kt
typealias Tasks = List<Task>
fun Tasks.findTask(id: String?) = firstOrNull { it.id == id }
调用
//在申明的时候不用暴露类型?
private var oldTasks: Tasks? = null
oldTasks?.findTask(lastId)
Java代码
TasksKt.java
import java.util.List;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/* compiled from: Tasks.kt */
public final class TasksKt {
@Nullable
public static final Task findTask(@NotNull List<Task> $receiver, @Nullable String id) {
Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");
int $i$f$firstOrNull = 0;
for (Object next : $receiver) {
if (Intrinsics.areEqual(((Task) next).getId(), (Object) id) != null) {
break;
}
}
Object next2 = null;
return (Task) next2;
}
}
调用
List list = this.oldTasks;
TasksKt.findTask(list , lastId)
不要纠结这个Task啊 他可以是Any类型
其他:
Intrinsics.areEqual()相当于 Java 的 ‘==’