Kotlin安卓称王?Java如何调用Kotlin的高级特性?_android kt context class

this.addFlags(flag)
}
if (this !is Activity) {
this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
if (bundle != null) {
putExtras(bundle.toBundle()!!)
}
}
startActivity(intent)
}

我们可用的一些扩展函数和一些不可用的扩展函数:

可以看到 ActivityExt 类中的部分扩展函数不能使用。一些内联函数+标注泛型的扩展方法确是无法使用。(还我用的不对吗?不知道有没有大佬指点!)

四、Java调用KT高阶函数

高阶函数就是可以当参数方法函数,例如最简单的高阶函数对象 () -> Unit 这种函数在转成 Java 的过程会生成对应的 Function 接口。我们直接 new Function 的匿名接口对象即可。

比如我们定义一些高级函数的方法:

class KotlinDemo {

fun String.setValueCallback(block: () -> Unit) {

block()
}

fun setValueCallback2(block: () -> Unit, action: (Int) -> Int) {

block()

val action1 = action(1)
YYLogUtils.w(“我收到处理的值了-计算的结果:$action1”)
}

}

那么我在Java中怎么调用呢?

public void demo2(View view) {

KotlinDemo demo = new KotlinDemo();

demo.setValueCallback(“str”, new Function0() {
@Override
public Unit invoke() {

ToastUtils.INSTANCE.makeText(mActivity, “我被回调了!!”);

return null;
}
});

demo.setValueCallback2(new Function0() {
@Override
public Unit invoke() {

YYLogUtils.w(“这里没有返回值,我回调到我就行了”);

return null;
}
}, new Function1<Integer, Integer>() {
@Override
public Integer invoke(Integer integer) {

YYLogUtils.w(“这里有返回值,回调到这里,我还需要处理运算,我的上级才能收到我处理的值”);

return integer + 10;
}
});

}

打印的结果:

高阶函数的Java调用可以说是后续的基础,关于 Function 的接口,从Function1 到 Function22 Kotlin给我们定义了20多个接口对象,只是用于区分有多少个参数,本质都是一样的。

不会真有人定义这么多参数吧,我最多用到三个参数 😅 😅

五、Java调用KT的SAM方式

其实Sam是基于Kotlin的简化方式,对应Java调用Kotlin来说其实是一样的,它只适应于Kotlin。

比如:

interface MyCustomCallback {

fun onCallback()
}


fun interface MyCustomCallback {

fun onCallback()
}


fun setSamMethod(callback: MyCustomCallback) {

callback.onCallback()
}

在Java中是一样的调用

public void demo5(View view) {

KotlinDemo demo = new KotlinDemo();

demo.setSamMethod(new MyCustomCallback() {
@Override
public void onCallback() {
YYLogUtils.w(“回调到了”);
}
});
}

只是在Kotlin语言中new的方式不同罢了:

fun setValueCallback2(block: MyCustomCallback.() -> Unit) {

block(object : MyCustomCallback {
override fun onCallback() {
YYLogUtils.w(“对方调用了,然后我来继续执行”)
}
})

}


fun setValueCallback2(block: MyCustomCallback.() -> Unit) {

block(MyCustomCallback { YYLogUtils.w(“对方调用了,然后我来继续执行”) })

}

其实是和高阶函数的调用比较类似,只是一个是我们自己定义的接口,一个是高阶函数Java转换的Function接口,使用起来是一样的。

六、Java调用KT高阶扩展函数

什么叫高阶扩展函数,其实就高阶函数,只是把原本回调的对象类型放在了前面以扩展的方式表达。以扩展的方式定义高阶函数,我把它叫做高阶扩展函数,但其本质还是高阶函数。

举一个很简单的例子

fun String.setValueCallback11(block: Industry.(Int) -> Unit) {
block(Industry(0, this, “123”, “456”), 10)
}

fun String.setValueCallback12(block: (Industry, Int) -> Unit) {
block(Industry(0, this, “123”, “456”), 10)
}

前者是高阶扩展函数,后者是高阶函数,使用的方式是一样的,只是高阶函数回调的时候一个需要用it或者指定变量接收,而高阶扩展函数只需要this接收,并且高阶扩展函数默认在回调的第一个参数上。

例如:

“test”.setValueCallback11 { int ->
YYLogUtils.w(“收到回调:industry:” + this.toString() + " int:" + int)
}

“test”.setValueCallback12 { industry, int ->
YYLogUtils.w(“收到回调:industry:” + industry.toString() + " int:" + int)
}

一个直接用this,另一种需要用it或者自定义名称来接收。用起来都是一样的,只是使用高阶扩展函数的话,会有一些简写方式更加方便,(如果不懂的话可能会更懵吧)

如何定义高阶扩展函数

这种方式有几种定义方式,以函数的类型定义为扩展函数定义和非扩展函数定义。参数又分基本类型,自定义类型,与接口类型。

下面都会讲到,先从简单的常用的讲起。

基本数据类型:

//这种比较常见
fun String.setValueCallback(block: String.() -> Unit) {

block(this.length.toString())
}


demo.setValueCallback(“test”, new Function1<String, Unit>() {
@Override
public Unit invoke(String s) {
YYLogUtils.w(“看看我收到的什么:” + s);
return null;
}
});

使用扩展方法再加上高阶扩展函数的参数,我们就可以直接使用this。就可以直接拿到数据设置回调。

这样的方式主要用于直接回调给对方

打印结果:

自定义对象类型:

如果我们修改高阶扩展函数的对象,你看这样就不协调了,String的扩展方法,确实回调的Industry对象

fun String.setValueCallback(block: Industry.() -> Unit) {
//直接回调给对方
block(this.length.toString())
}

如果还是使用String的参数,上面的用法就会报错,我们应该回调Industry的对象。

fun String.setValueCallback(block: Industry.() -> Unit) {
//直接回调给对方
block(Industry(0, this, “123”, “456”))
}

我们把String的扩展this当做Industry的构造参数的一个属性,这样才能回调一个Industry对象给Java

看Log打印,回调的就是Industry

接口类型:

除了用对象做高阶扩展函数,我们还能以接口的形式做高阶扩展函数。

//还能设置不相关的对象扩展
fun setValueCallback2(block: MyCustomCallback.() -> Unit) {

block(object : MyCustomCallback {
override fun onCallback() {

}
})

}

使用接口类型做我参数的扩展,这里我们需要new一个对象给调用者。就导致这种方法是 回调给对方调用再通过对方回调给自己

在Java的代码中我们可以直接调用接口的方法,让对方去执行

public void demo3(View view) {
KotlinDemo demo = new KotlinDemo();

demo.setValueCallback2(new Function1<MyCustomCallback, Unit>() {
@Override
public Unit invoke(MyCustomCallback myCustomCallback) {

//调用
myCustomCallback.onCallback();

return null;
}
});
}

打印的Log如下:

不管是用Java代码去调用,还是用Ktolin代码调用,本质是一样的。

需要注意方法的参数,是否是基本类型的高阶扩展函数,还是对象类型的高阶扩展函数,还是接口类型的高阶扩展函数。这会导致是回调的方式不同。

而方法本身是否是扩展函数,则相对没有那么重要,主要是看方便我们能否使用this,如果需要this对象就用扩展函数,如果不需要那我们可以不用。

关于高阶扩展函数的补充

其实前文也说了,本质还是高阶扩展函数,只是区分是否用this接收而已,所以高阶扩展函数也是针对Kotlin来说的,对Java语言来说,还是以高阶函数的方式来处理。

举例说明:

fun String.setValueCallback1(block: String.(Int) -> Unit) {
block(this, 10)
}

Java代码中使用这一种高阶扩展函数:

KotlinDemoKt.setValueCallback1(“test”, new Function2<String, Integer, Unit>() {
@Override
public Unit invoke(String s, Integer integer) {
YYLogUtils.w(“收到回调:s:” + s + “integer:” + integer);
return null;
}
});

可以看到Java语言可不管你扩不扩展,对它来说就是两个参数,我也不能用this什么的,我只能用转换过的Function。可以看到Kotlin虽然定义的是Int,但是Java接收到的是 Function2 是两个参数的回调,顺序是第一个是String第二个是Int。

前文讲到的基本类型,对象类型,接口类型,这里做一个全部的Demo

fun String.setValueCallback0(block: (Int) -> Unit) {
block(10)
}

fun String.setValueCallback1(block: String.(Int) -> Unit) {
block(this, 10)
}

fun String.setValueCallback11(block: Industry.(Int) -> Unit) {
block(Industry(0, this, “123”, “456”), 10)
}

fun String.setValueCallback12(block: (Industry, Int) -> Unit) {
block(Industry(0, this, “123”, “456”), 10)
}

fun String.setValueCallback13(block: MyCustomCallback.(String) -> Unit) {

block(MyCustomCallback { YYLogUtils.w(“对方调用了,然后我来继续执行”) }, this + “加点后缀”)

}

为了方便理解,回调的时候我故意没有省略this,一般大家写代码都会省略this。

如果是Kotlin代码调用,很简单

“test”.setValueCallback1 { int ->
YYLogUtils.w(“收到回调:str:” + this + " int:" + int)
}

“test”.setValueCallback11 { int ->
YYLogUtils.w(“收到回调:industry:” + this.toString() + " int:" + int)
}

“test”.setValueCallback12 { industry, int ->
YYLogUtils.w(“收到回调:industry:” + industry.toString() + " int:" + int)
}

“test”.setValueCallback13 { str ->
YYLogUtils.w(“收到回调:callback:” + this + " str:" + str)
this.onCallback()
}

打印如下:

如果是Java代码调用:

public void demo2(View view) {

KotlinDemo demo = new KotlinDemo();

KotlinDemoKt.setValueCallback1(“test”, new Function2<String, Integer, Unit>() {
@Override
public Unit invoke(String s, Integer integer) {
YYLogUtils.w(“收到回调:s:” + s + “integer:” + integer);
return null;
}
});

KotlinDemoKt.setValueCallback11(“test”, new Function2<Industry, Integer, Unit>() {
@Override
public Unit invoke(Industry industry, Integer integer) {
YYLogUtils.w(“收到回调:industry:” + this.toString() + " integer:" + integer);
return null;

}
});

KotlinDemoKt.setValueCallback12(“test”, new Function2<Industry, Integer, Unit>() {
@Override
public Unit invoke(Industry industry, Integer integer) {
YYLogUtils.w(“收到回调:industry:” + this.toString() + " integer:" + integer);
return null;

}
});

KotlinDemoKt.setValueCallback13(“test”, new Function2<MyCustomCallback, String, Unit>() {
@Override
public Unit invoke(MyCustomCallback myCustomCallback, String s) {

YYLogUtils.w(“收到回调:callback:” + myCustomCallback.toString() + " str:" + s);
myCustomCallback.onCallback();

return null;
}
});

可以看到这种方式对Java是没有效果的,和高阶函数的使用是一模一样的。

打印Log如下:

结论:这种以高阶函数定义的扩展函数,对Java的调用来说没效果,只是Kotin语言的一些简化。

七、Java调用KT的DSL方式

按照顺序一步一步的来,我们会了Java调用扩展函数和高阶扩展函数,那么在此基础上我们就能完成Kotlin的DSL调用了。

我们都知道DSL的简化规则是基于高阶扩展函数间接实现的(也可以直接高阶函数实现,不过使用的时候就需要用it去点出方法,不够优雅,所以一般大家都用高阶扩展函数的方式去实现)。

那么我们学了Java调用高阶扩展函数之后,再回头看看DSL的调用有什么不同。

之前的文章已经讲过DSL定义的几种方式,这里不多BB,直接快速过一次代码:

fun TestNet.setOnSuccessCallbackDsl(init: SuccessCallbackImpl.() -> Unit) {
val listener = SuccessCallbackImpl()
init(listener)
this.setOnSuccessCallback(listener)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-SUeRDN6a-1712687433906)]
[外链图片转存中…(img-fLF8qzQ5-1712687433906)]
[外链图片转存中…(img-5ho85j88-1712687433907)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
[外链图片转存中…(img-OVYDVjm8-1712687433907)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在RecyclerView上显示项目,您需要执行以下操作: 1. 创建一个适配器类来管理和显示数据。适配器类必须继承RecyclerView.Adapter类并实现三个方法:onCreateViewHolder()、onBindViewHolder()和getItemCount()。onCreateViewHolder()方法负责创建视图持有者ViewHolder,onBindViewHolder()方法负责绑定数据到ViewHolder,getItemCount()方法返回数据源中项目的数量。 2. 创建一个布局文件来定义RecyclerView项目的外观。此布局将用作RecyclerView.Adapter的参数之一。 3. 在主活动(Activity)中实例化RecyclerView,并将其与适配器和数据源连接。您需要提供一个布局管理器(LayoutManager)来指定RecyclerView项目的排列方式。 以下是一个简单的示例: 1. 创建适配器类 ``` class MyAdapter(private val items: List<String>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.my_item_layout, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.textView.text = items[position] } override fun getItemCount(): Int { return items.size } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val textView: TextView = itemView.findViewById(R.id.my_text_view) } } ``` 2. 创建布局文件 my_item_layout.xml: ``` <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/my_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" /> </LinearLayout> ``` 3. 在主活动中实例化RecyclerView MainActivity.kt: ``` class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val items = listOf("Item 1", "Item 2", "Item 3") val adapter = MyAdapter(items) val layoutManager = LinearLayoutManager(this) recycler_view.adapter = adapter recycler_view.layoutManager = layoutManager } } ``` activity_main.xml: ``` <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 这将在RecyclerView上显示三个项目,每个项目都由my_item_layout.xml定义的布局文件呈现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值