Kotlin от lazy выдает неожиданное исключение NullPointerException при достижении. При достижении отладчика это правильно оценивается, и findViewById(R.id.image_view_icon) возвращает допустимое представление ImageView, поэтому я не могу понять, почему это происходит - почему выдается исключение NullPointerException, если это не равно нулю и если представление существует и уже заполнено в момент ленивой инициализации?
Случай использования пример:
У меня есть собственный компонент представления Android — простое представление меток SimpleLabelView. Этот компонент поддерживает установку значка, и по умолчанию его реализация устанавливает его как составное изображение, которое можно нарисовать для метки TextView..
Теперь я хочу создать новый компонент CompactIconLabelView, который расширяет существующий SimpleLabelView. Новый CompactIconLabelView использует другой макет, и теперь я хочу изменить поведение установки значка - вместо того, чтобы устанавливать его как рисуемый для метки, я хочу установить этот рисуемый пользовательский ImageView который содержится в этом новом чертеже. Для этого мне нужно лениво инициализировать данный ImageView
Ошибка
Код: Выделить всё
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object kotlin.Lazy.getValue()' on a null object reference
at hr.simplifystay.sharedmodelslibrary.customViews.label.CompactIconLabelView.getIconImageViewThatCrashes(CompactIconLabelView.kt:40)
at hr.simplifystay.sharedmodelslibrary.customViews.label.CompactIconLabelView.setIcon(CompactIconLabelView.kt:37)
at hr.simplifystay.sharedmodelslibrary.customViews.label.SimpleLabelView.(SimpleLabelView.kt:157)
at hr.simplifystay.sharedmodelslibrary.customViews.label.CompactIconLabelView.(CompactIconLabelView.kt:24)
at hr.simplifystay.sharedmodelslibrary.customViews.label.CompactIconLabelView.(CompactIconLabelView.kt:18)
at hr.simplifystay.sharedmodelslibrary.customViews.label.CompactIconLabelView.(Unknown Source:14)
Код: Выделить всё
SimpleLabelViewКод: Выделить всё
open class SimpleLabelView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int = R.attr.labelViewStyle,
defStyle: Int = R.style.Theme_Simplify,
@LayoutRes layoutResId: Int = R.layout.layout_simple_label
) : ConstraintLayout(context, attrs, defStyleAttr, defStyle) {
@StyleableRes
private val iconAttr = R.styleable.SimpleLabelView_icon
open var icon: Drawable? = null
set(value) {
field = value
label.setCompoundDrawablesRelativeWithIntrinsicBounds(value, null, null, null)
}
val label: MaterialTextView
init {
val view = inflate(context, layoutResId, this)
... some initializing code
icon = typedArray.getDrawable(iconAttr) // Line 157 from stacktrace
... more code
}
}
Код: Выделить всё
CompactIconLabelViewКод: Выделить всё
open class CompactIconLabelView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int = R.attr.labelViewStyle,
defStyle: Int = R.style.Theme_Simplify,
@LayoutRes layoutResId: Int = R.layout.layout_compact_icon_label
) : SimpleLabelView(context, attrs, defStyleAttr, defStyle, layoutResId) {
override var icon: Drawable? = null
get() = super.icon
set(value) {
field = value
// This works
if (!(::iconImageView.isInitialized))
iconImageView = findViewById(R.id.image_view_icon)
iconImageView.setImageDrawable(value)
// This crashes
iconImageViewThatCrashes.setImageDrawable(value) // Line 37 from stacktrace
}
private val iconImageViewThatCrashes: ShapeableImageView by lazy { findViewById(R.id.image_view_icon) } // Line 40 from stacktrace
private lateinit var iconImageView: ShapeableImageView
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... -lazy-init
Мобильная версия