Kotlin Delegate 代码笔记

Kotlin Delegate 代码笔记

类代理

1
2
3
interface ThemeActivityDelegate {
val currentTheme: Theme
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ThemeActiviteDelegateImpl(
private val observeThemeUseCase: ObserveThemeModeUseCase,
private val getThemeUseCase: GetThemeUseCase
) : ThemeActivityDelegate {
init {
observeThemeUseCase.execute(Unit)
}

override val theme: LiveData<Theme> by lazy(NONE) {
observeThemeUseCase.observe().map {
if (it is Success) it.data else Theme.SYSTEM
}
}

override val currentTheme: Theme
get() = getThemeUseCase.executeNow(Unit).let {
if (it is Success) it.data else Theme.SYSTEM
}
}
1
2
3
4
5
class MainActivityViewModel(
themedActivityDelegate: ThemedActivityDelegate
) :ViewModel(),ThemeActivityDelegate by themedActivityDelegate {

}
1
2
3
4
5
6
7
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//使用
val theme = viewModel.currentTheme
}
}

属性代理

1
2
3
4
interface PreferenceStorage {
var selectedTheme: String?
var observableSelectedTheme: LiveData<String>
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class SharedPreferenceStorage (context: Context) : PreferenceStorage {
companion object {
const val PREF_DARK_MODE_ENABLED = "pref_dark_mode"
const val PREFS_NAME = "prefs"
}

private val observableSelectedThemeResult = MutableLiveData<String>()

private val prefs: Lazy<SharedPreferences> = lazy {
context.getSharedPreferences(
PREFS_NAME, MODE_PRIVATE
).apply {
registerOnSharedPreferenceChangeListener(changeListener)
}
}

private val changeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when (key) {
// 当数据改变时,将改变的数据放到一个 LiveData 中
PREF_DARK_MODE_ENABLED -> observableSelectedThemeResult.value = selectedTheme
}

}

/**
* Kotlin 属性代理
*/
override var selectedTheme: String? by StringPreference(
prefs,
PREF_DARK_MODE_ENABLED,
Theme.SYSTEM.storageKey
)

override var observableSelectedTheme: LiveData<String>
get() {
observableSelectedThemeResult.value = selectedTheme
return observableSelectedThemeResult
}
set(_) = throw IllegalAccessException("不能对此实例进行赋值!")
}

属性代理例子

  • 构造像下面这样得代码:

    1
    2
    3
    override var selectedTheme by StringPreference(
    prefs, PREF_DARK_MODE_ENABLED, Theme.SYSTEM.storageKey
    )
  • 或:

    1
    private val viewModel: MainViewModel by viewModels { viewModelFactory }
  • 拿 selectedTheme 举例子,首先定义一个 interface

    1
    interface PreferenceStorage(var selectedTheme: String?)
  • 定义代理类,这里使用了标准库 ReadWriteProperty 来实现(重点)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class StringPreference(
    private val preferences: Lazy<SharedPreferences>,
    private val name: String,
    private val defaultValue: String?
    ) : ReadWriteProperty<Any, String?> {

    override fun getValue(thisRef: Any, property: KProperty<*>): String? {
    return preferences.value.getString(name, defaultValue)
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: String?) {
    preferences.value.edit { putString(name, value) }
    }
    }
  • 实现上面的接口,实现 selectedTheme 对象赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class SharedPreferenceStorage(context: Context) : PreferenceStorage {
    context.applicationContext.getSharedPreferences(
    PREFS_NAME, MODE_PRIVATE
    ).apply {
    registerOnSharedPreferenceChangeListener(changeListener)
    }

    private val changeListener = OnSharedPreferenceChangeListener { _, key ->
    when (key) {
    PREF_DARK_MODE_ENABLED -> observableSelectedThemeResult.value = selectedTheme
    }
    }
    //上面只是初始化 SharedPreference

    override var selectedTheme by StringPreference(
    prefs, PREF_DARK_MODE_ENABLED, Theme.SYSTEM.storageKey
    )
    }

如果要实现像下面这样:

1
private val viewModel: MainViewModel by viewModels { viewModelFactory }

去掉上面的接口,StringPreference 修改成 viewModels,构造函数定义成 lambda 即可