https://kotlinlang.org/docs/reference/android-overview.html
记录
let, also,apply,run
https://blog.csdn.net/u013064109/article/details/78786646
简单分析下,also和apply一样都是返回自己, let和run一样返回花括号代码块最后一行的返回值
另外一样的2种区别就在于代码块里用it还是this代替变量,而this可以省略不写。

如上图,结果就是 2个hello,以及7和5
简单看下源码
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
public inline fun <T, R> T.run(block: T.() -> R): R = block()
看到源码可能感觉和我们的写法不一样。其实原因很简单,kotlin里一个函数可以作为参数的,完事这个函数可以写到括号外边。
比如 T.apply({//函数块}) 可以写成 T.apply(){//函数块}
对于let和run,如果要主动return一个东西,这样写的// return@run 333
在看demo的时候看到这些代码,扩展函数
可以注意到方法名字前有个xxx. 的东西,这个就是声明对哪个类进行扩展
/**
* The `fragment` is added to the container view with id `frameId`. The operation is
* performed by the `fragmentManager`.
*/
fun AppCompatActivity.replaceFragmentInActivity(fragment: Fragment, @IdRes frameId: Int) {
supportFragmentManager.transact {
replace(frameId, fragment)
}
}
/**
* The `fragment` is added to the container view with tag. The operation is
* performed by the `fragmentManager`.
*/
fun AppCompatActivity.addFragmentToActivity(fragment: Fragment, tag: String) {
supportFragmentManager.transact {
add(fragment, tag)
}
}
fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit) {
setSupportActionBar(findViewById(toolbarId))
supportActionBar?.run {
action()
}
}
/**
* Runs a FragmentTransaction, then calls commit().
*/
private inline fun FragmentManager.transact(action: FragmentTransaction.() -> Unit) {
beginTransaction().apply {
action()
}.commit()
}
代码里这样用的
setupActionBar(R.id.toolbar) {
setHomeAsUpIndicator(R.drawable.ic_menu)
setDisplayHomeAsUpEnabled(true)
}
其实原本应该这样的,不过最后一个参数是一个函数的话,可以直接把括号的实现提到圆括号外面,就成了上边的写法了
setupActionBar(R.id.toolbar, {
setHomeAsUpIndicator(R.drawable.ic_menu)
setDisplayHomeAsUpEnabled(true)
})
when
java 中的switch 在kotlin里的写法,
when(xxx){
is Int->{
}
in 0..10->{
}
1->{
}
2->{
}
3,4->{}
else->{}
}
2个方法互相引用的时候
java代码如下,我是2个runnable 互相调用
private void starte(){
handler.postDelayed(r1,1000);
}
Handler handler=new Handler();
Runnable r1=new Runnable() {
@Override
public void run() {
System.out.println("==========1");
handler.postDelayed(r2,1111);
}
};
Runnable r2=new Runnable() {
@Override
public void run() {
System.out.println("==========2");
handler.postDelayed(r1,1111);
}
};
kotlin代码如下
internal var handler = Handler()
internal var r1: Runnable = Runnable {
println("==========1")
handler.postDelayed(r2, 1111)
}
internal var r2: Runnable = Runnable {
println("==========2")
handler.postDelayed(r1, 1111)
}
private fun starte() {
handler.postDelayed(r1, 1000)
}
看下转化,加了internal,这个是限定同一模块下可以访问,非必需。
关键有的地方 r2: Runnable 这个,2个Runnable必须有一个需要加冒号声明类型,否则就报错。
Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly
中文:类型检查遇到了递归问题。最简单的解决方法:显式地指定声明的类型。
可以看到上边都是简化后的写法了。如果这个时候要使用this,就不行了,得写完整的
如下
internal var r2: Runnable = object : Runnable {
override fun run() {
println("==========2")
handler.postDelayed(r1, 1111)
handler.postDelayed(this, 2222)
Runnable { handler.postDelayed(this, 2222) }.run()
}
}
循环的几种写法
下边的代码结果都一样,都是从0到4循环的,从大到小的话可以用 downto关键字
private fun forTest(){
//循环N次,from 0 start
repeat(5){
println("a============$it")
}
for(i in 0 ..4){
println("b==========$i")
}
for(i in 0 until 5){
println("c==========$i")
}
(0..4).forEach {
println("d==============$it")
}
}
set get
//set的简化写法
var tasks: List<Task> = tasks
set(tasks) {
field = tasks
notifyDataSetChanged()
}
//get的简化写法
override var isActive: Boolean = false
get() = isAdded
thread ,简化写法如下,不需要start,内部默认构造方法里start为true的。
thread {
}
问题记录
1~
java 代码 Object obj=new Object(); obj.wait();
kotlin里的Any()对象没有wait()方法,不知道转成kotlin之后咋写。
解决办法,kt里继续new一个Object对象而不是any对象。
https://www.jianshu.com/p/3963e64e7fe7
2~
java代码的switch(index){
case 2:
if(index<10){
//xxxxxxxxxxx
break;
}
if(index<100){
//xxxxxxxxx
break;
}
//xxxxxxxxxx
break;
}
kotlin里没有break,这种半路很多break的难道只能用一堆if和else来写吗?
双冒号::
可以理解为把一个方法当对象处理,如下
class A {
lateinit var b:B
init {
b=B().apply {
this.callbackA=this@A::testA//把testA这个方法传递给B里边的一个变量callbackA了
}
}
fun testA(name: String,age:Int){
}
}
class B{
var callbackA:((String,Int) ->Unit)?=null//这里对应写出参数的类型,返回的类型好匹配,因为是可以为空的,所以括起来加个问号
fun testB(){
callbackA?.invoke("jerry",33)
}
}
上边的可以用来写我们平时用的Callback。
如果是java,我们一般是定义一个interface,完事定义一个interface的变量,然后用的时候实例化一个interface调用
然后看下改版后的写法
如下自定义的类
class ItemTouchListener{
//某个地方调用
singleTapCallback?.invoke(position,rv.getChildViewHolder(child))
//然后定义的回调
var singleTapCallback:((position: Int, viewHolder: RecyclerView.ViewHolder)->Unit)?=null
}
然后是正式使用的地方
rv_temp.addOnItemTouchListener(ItemTouchListener(rv_temp).apply {
singleTapCallback=this@FragmentTempTest::singleTab
//或者这样调用也可以
singleTapCallback={position, viewHolder ->
}
})
//这个就是我们的回调实现方法拉。
fun singleTab(position: Int, viewHolder: RecyclerView.ViewHolder){
}
这里还有一些
https://blog.csdn.net/lmo28021080/article/details/81505211
网友评论