【问题标题】:Custom View constructor in Android 4.4 crashes on Kotlin, how to fix?Android 4.4 中的自定义视图构造函数在 Kotlin 上崩溃,如何修复?
【发布时间】:2017-07-28 05:41:06
【问题描述】:

我有一个使用 JvmOverloads 用 Kotlin 编写的自定义视图,我可以有默认值。

class MyView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyle, defStyleRes)

在 Android 5.1 及更高版本中一切正常。

但是它在 4.4 中崩溃,因为 4.4 中的构造函数没有defStyleRes。我怎么能在 5.1 及更高版本中支持 defStyleRes 但在 4.4 中不支持,而无需像在 Java 中那样显式定义 4 个构造函数?

注意:以下内容在 4.4 中可以正常工作,但随后我们失去了 defStyleRes

class MyView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : LinearLayout(context, attrs, defStyle)

【问题讨论】:

标签: android kotlin android-custom-view android-4.4-kitkat


【解决方案1】:

我有办法做到这一点。只需重载前 3 个函数即可,将第 4 个函数留给 Lollipop 及以上使用 @TargetApi 包装。

class MyView : LinearLayout {
    @JvmOverloads
    constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
        : super(context, attrs, defStyleAttr)

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int)
        : super(context, attrs, defStyleAttr, defStyleRes)
}

【讨论】:

  • 这是一个有效的答案。好@Elye
  • 如何使用@Elye 的这种方法访问 init 函数中的 attrs?
  • @niegus 可以,只需创建自己的 initialize 函数即可
【解决方案2】:

最好的办法就是这样上课。

class MyView : LinearLayout {
    @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr)
    @TargetApi(Build.VERSION_CODES.LOLLIPOP) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
}

【讨论】:

  • 这又回到了定义所有 4 个构造函数的旧方式:(
  • 这就是 Android 的工作方式,不管 Kotlin 的语法有多大帮助,它是 Android 需要 Boilerplate 的那个:D 无论如何,你可以使用默认值来减少这些,但你必须至少使用2个构造函数
  • @Elye 我已经编辑了我的答案以显示与 2 个构造函数相同的功能
  • 嗨,这和我的问题一样。它将在 4.4 崩溃
  • 是的,我会添加它。不要忘记标记它是正确的答案。
【解决方案3】:

只需像这样定义构造函数:

constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
@TargetApi(21)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

【讨论】:

    猜你喜欢
    • 2011-02-22
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多