android-recyclerview - Kotlin 客户界面声明

标签 android-recyclerview kotlin

我在将现有的 Java 代码转换为 Kotlin 时遇到了一些问题,特别是在我与回收 View 一起使用的自定义点击监听器中。这是我到目前为止所得到的。

//this is the click listener interface (in Kotlin)
interface RecyclerClickListener {
  fun onClick(view: View, position: Int)
}

在 Java 中,这就是我创建和使用接口(interface)的方式
RecyclerClickListener clickListener = (view1, position) -> {
        setSelectedDate(dateCards.get(position).getDateTime());
        DateCardAdapter adapter = (DateCardAdapter) date_recycler_view.getAdapter();
        adapter.setSelected(position);
    };
    DateCardAdapter cardAdapter = new DateCardAdapter(dateCards, getActivity(), clickListener, true );

现在这就是我在 Kotlin 中尝试的方式(其中大部分是在 Android Studio 中自动转换的)
val listener: RecyclerClickListener = { view1: View, position: Int ->
        setSelectedDate(dateCards[position].dateTime)
        val adapter = sun_date_recycler_view.adapter as DateCardAdapter
        adapter.setSelected(position)
    } as RecyclerClickListener
    val cardAdapter = DateCardAdapter(dateCards, activity!!, listener, true)

但是当我启动我的应用程序时,我在尝试创建监听器时不断收到 ClassException
Caused by: java.lang.ClassCastException: .fragments.SunFragment$onViewCreated$listener$1 cannot be cast to .interfaces.RecyclerClickListener

最佳答案

您声明的 lambda 类型为 (View, Int) -> Unit ,它不是 RecyclerClickListener 的子类型. Kotlin 有一个名为 SAM conversion 的功能。这允许您使用 lambdas 创建功能(单一方法)接口(interface)的匿名实例,但这仅适用于 Java 中定义的接口(interface)。

(...) note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.


  • 这是您的第一个(并且可能是目前最好的)解决方案 - 在 Java 中定义接口(interface),您将能够毫无问题地在两种语言中使用 lambda。
  • 另一种是使用 Kotlin 文档建议的函数类型,这需要您使用类型 (View, Int) -> Unit而不是定义一个新的接口(interface)。这样,您在 Kotlin 和 Java 中的 lambda 都可以按原样工作(没有强制转换)。您可以使用 typealias在 Kotlin 代码中通过名称而不是函数类型来引用它,但这在 Java 中是不可见的:
    typealias RecyclerClickListener = (String, Int) -> Unit
    

    您还必须明确返回 Unit.INSTANCE在任何 Java lambda 的末尾:
    (view, position) -> {
        System.out.println("Clicked");
        return Unit.INSTANCE;
    }
    

  • 您可以找到关于 Kotlin 接口(interface) future 可能支持的 SAM 转换的讨论 here .

    关于android-recyclerview - Kotlin 客户界面声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49518823/

    相关文章:

    java - Android studio RecyclerView 按日期分组?

    android - 如何在recycleview的gridlayout中设置自动列?

    android - 突出显示 RecyclerView 中的选定项目

    android - ViewModel中的LiveData类型不匹配

    android - 应用内更新的 JobCancellationException

    android - 如何在回收商查看项目点击时跟踪项目选择?

    android - 在 RecyclerView 中回收时,项目 View 未正确测量

    kotlin - 如何在 Webview 和 Retrofit2 Okhttp3 之间共享 cookie

    android - Flutter:共享存储(存储访问框架 API)隐藏子目录中文件的权限不起作用

    Android数据绑定(bind)问题: Missing return statement in generated code while using with a custom view?