ste*_*wpf 4 android observable android-jetpack-compose
我有一个更复杂的对象,我希望 Jetpack Compose 可以观察它。但是我不能使用
// in my view model
var observableProperty by mutableStateOf(myObject)
Run Code Online (Sandbox Code Playgroud)
因为我需要myObject保留它的参考。所以我的计划是使用
// in my view model
var observableProperty = myObject
Run Code Online (Sandbox Code Playgroud)
并使其myObject自身实现MutableState接口。但是我不明白如何在自定义类中实现这一点,特别是如何向观察者(Jetpack Compose)发出更改通知?
我目前拥有的简化示例:
class MyComplexObject(){
private val map = mutableMapOf<String,Any>()
fun setValue(key: String, value: Any) {
map[key] = value
// how to notify about a change? <================
}
fun getValue(key: String) : Any? {
return map[key]
}
}
Run Code Online (Sandbox Code Playgroud)
您不必让复杂对象实现 MutableState。您可以创建一个包含mutableStates 和其他不需要在更改时触发重组的对象的复杂对象。这是 JetSnack 应用程序中的常见模式。
@Stable
class SearchState(
query: TextFieldValue,
focused: Boolean,
searching: Boolean,
categories: List<SearchCategoryCollection>,
suggestions: List<SearchSuggestionGroup>,
filters: List<Filter>,
searchResults: List<Snack>
) {
var query by mutableStateOf(query)
var focused by mutableStateOf(focused)
var searching by mutableStateOf(searching)
var categories by mutableStateOf(categories)
var suggestions by mutableStateOf(suggestions)
var filters by mutableStateOf(filters)
var searchResults by mutableStateOf(searchResults)
val searchDisplay: SearchDisplay
get() = when {
!focused && query.text.isEmpty() -> SearchDisplay.Categories
focused && query.text.isEmpty() -> SearchDisplay.Suggestions
searchResults.isEmpty() -> SearchDisplay.NoResults
else -> SearchDisplay.Results
}
}
Run Code Online (Sandbox Code Playgroud)
并且你用记住来包装这个对象,以防止在每次重组时不实例化
@Composable
private fun rememberSearchState(
query: TextFieldValue = TextFieldValue(""),
focused: Boolean = false,
searching: Boolean = false,
categories: List<SearchCategoryCollection> = SearchRepo.getCategories(),
suggestions: List<SearchSuggestionGroup> = SearchRepo.getSuggestions(),
filters: List<Filter> = SnackRepo.getFilters(),
searchResults: List<Snack> = emptyList()
): SearchState {
return remember {
SearchState(
query = query,
focused = focused,
searching = searching,
categories = categories,
suggestions = suggestions,
filters = filters,
searchResults = searchResults
)
}
}
Run Code Online (Sandbox Code Playgroud)
任何MutableStates 中的任何更改都将触发读取这些值的可组合范围中的重组。
常用的记住函数(例如 RememberScrollState 和其他一些函数)也使用这种方法。
@Stable
class ScrollState(initial: Int) : ScrollableState {
/**
* current scroll position value in pixels
*/
var value: Int by mutableStateOf(initial, structuralEqualityPolicy())
private set
/**
* maximum bound for [value], or [Int.MAX_VALUE] if still unknown
*/
var maxValue: Int
get() = _maxValueState.value
internal set(newMax) {
_maxValueState.value = newMax
if (value > newMax) {
value = newMax
}
}
/**
* [InteractionSource] that will be used to dispatch drag events when this
* list is being dragged. If you want to know whether the fling (or smooth scroll) is in
* progress, use [isScrollInProgress].
*/
val interactionSource: InteractionSource get() = internalInteractionSource
internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()
private var _maxValueState = mutableStateOf(Int.MAX_VALUE, structuralEqualityPolicy())
// Rest of the code
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1917 次 |
| 最近记录: |