#android #kotlin
#Android #kotlin
Вопрос:
Я использую AutoclearedValue в Android, и на моем старом планшете, который работает под управлением Android 4.4.4, я всегда получаю исключение, подобное этому: никогда не следует вызывать auto-cleared-value get, если оно может быть недоступно из класса AutoclearedValue
Я не понимаю, почему, потому что на более новых устройствах я не получаю это исключение.
Сценарий следующий: я нажимаю элемент в recyclerview, после чего откроется другой фрагмент. В этом фрагменте я реализовал простой прослушиватель scrollview, он отлично работает. Когда я нажимаю кнопку «Назад», чтобы вернуться к предыдущему фрагменту, я получаю исключение.
Мой класс AutoClearedValue:
class AutoClearedValue<T : Any>(val fragment: Fragment) : ReadWriteProperty<Fragment, T> {
private var _value: T? = null
init {
fragment.lifecycle.addObserver(object: DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
viewLifecycleOwner?.lifecycle?.addObserver(object: DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
_value = null
}
})
}
}
})
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
return _value ?: throw IllegalStateException(
"should never call auto-cleared-value get when it might not be available"
)
}
override fun setValue(thisRef: Fragment, property: KProperty<*>, value: T) {
_value = value
}
}
/**
* Creates an [AutoClearedValue] associated with this fragment.
*/
fun <T : Any> Fragment.autoCleared() = AutoClearedValue<T>(this)
И мой слушатель, откуда берется исключение:
private fun initListeners() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.freightTaskRowDetailScrollView.setOnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
if (binding.showFab == true) {
if (scrollY <= oldScrollY) {
if (!binding.expandableFab.isShown)
binding.expandableFab.showHide()
} else {
if (binding.expandableFab.isShown)
binding.expandableFab.showHide()
}
}
}
} else {
binding.freightTaskRowDetailScrollView.viewTreeObserver
.addOnScrollChangedListener {
if (binding.showFab == true) { [this line]
if (!binding.freightTaskRowDetailScrollView.canScrollVertically(1)) {
if (binding.expandableFab.isShown)
binding.expandableFab.showHide()
}
if (!binding.freightTaskRowDetailScrollView.canScrollVertically(-1)) {
if (!binding.expandableFab.isShown)
binding.expandableFab.showHide()
}
}
}
}
}
Ответ №1:
Обновить:
В AutoClearedValue есть ошибка с точки зрения привязки к просмотру, вместо этого вы должны использовать класс, представленный по этой ссылке, для привязки к просмотру.
СТАРЫЙ ОТВЕТ
У вас СТАРАЯ версия этого класса.
Проверьте новую реализацию здесь: