Как преобразовать код в делегат с помощью Kotlin?

#kotlin

#kotlin

Вопрос:

Код A работает хорошо, я надеюсь преобразовать его в качестве делегата.

Но код B терпит неудачу, как я могу это исправить?

Код A

    private val _sortBy=my_sortBy()

    fun my_sortBy():MutableLiveData<ESortBy>{
        val index: String by PreferenceTool( mApplication, "sorByList", ESortBy.DateDesc.toString())
        return MutableLiveData<ESortBy>(ESortBy.valueOf(index))
    }
 

Код B

    private val _sortBy: MutableLiveData<ESortBy> by {
        val index: String by PreferenceTool( mApplication, "sorByList", ESortBy.DateDesc.toString())
        return MutableLiveData<ESortBy>(ESortBy.valueOf(index))
    }
    
 

Комментарии:

1. Вы бы прочитали kotlinlang.org/docs/reference/delegated-properties.html ?

Ответ №1:

Какой делегат вам нужен и почему? Если вы хотите инициализировать LivaData без my_sortBy функции, просто используйте функции области видимости.

 private val _sortBy = MutableLiveData<ESortBy>().apply {
    val index: String by PreferenceTool(mApplication, "sorByList", ESortBy.DateDesc.toString())
    value = ESortBy.valueOf(index)
}
 

или

 private val _sortBy = MutableLiveData<ESortBy>(run {
    val index: String by PreferenceTool(mApplication, "sorByList", ESortBy.DateDesc.toString())
    ESortBy.valueOf(index)
})
 

Ответ №2:

Вам не хватает присваивания ( = ).

 private val _sortBy = MutableLiveData<ESortBy> by {
    val index: String by PreferenceTool( mApplication, "sorByList", ESortBy.DateDesc.toString())
    return MutableLiveData<ESortBy>(ESortBy.valueOf(index))
}
 

Комментарии:

1. Спасибо! но ваш код не может быть скомпилирован.

2. Что это говорит? Я не смог попробовать, так как мне не хватает большинства классов.

Ответ №3:

Вам нужно создать реализацию вашего делегата свойств. Например, вы можете реализовать ReadOnlyProperty :

 private val _sortBy: MutableLiveData<ESortBy> by ReadOnlyProperty<Any, MutableLiveData<ESortBy>> { thisRef, property ->
    val index: String by PreferenceTool( mApplication, "sorByList", ESortBy.DateDesc.toString())
    MutableLiveData<ESortBy>(ESortBy.valueOf(index))
}
 

Комментарии:

1. Спасибо! return не допускается в вашем коде.

2. @HelloCW вы правы, я обновил ответ

3. Спасибо! ваш код может работать, какой способ лучше между вашим и Николой Деспотоски?

4. И еще, ReadOnlyProperty ключевое слово is? могу ли я переименовать ReadOnlyProperty в другое?

5. @HelloCW ReadOnlyProperty — это интерфейс из стандартной библиотеки. Вы не можете переименовать его, но вы можете создать псевдоним типа и использовать его вместо него: typealias Delegate<T, V> = ReadOnlyProperty<T, V>

Ответ №4:

Это зависит от того, какой из них инициализируется первым. Затем вам нужно создать и передать значение в a LiveData . Вы можете достичь этого с помощью LiveData функции расширения. Ключевое by слово недоступно внутри области действия функции, вам нужно быть осторожным, чтобы не использовать его.

 private val index: String by PreferenceTool( mApplication,"sorByList",ESortBy.DateDesc.toString())
private val _sortBy  by liveData {
        emit(ESortBy.valueOf(index)) 
} as MutableLiveData<ESortBy>
 

Для использования делегата вам понадобится LiveData-ktx liveData { }