我如何在 Jetpack Compose 中管理很多状态

How can I manage a lots of States in jetpack compose

我正在构建一个应用程序,它有很多输入字段,因此对于这些输入字段,我必须在我的 viewModel 中管理很多状态。

因此,我的 viewModel 一团糟。谁能指导我用干净的代码有效地处理这些状态。

android 官方文档中提到了我正在使用的状态管理模式。

我的 viewModels 看起来像这样-

@HiltViewModel
class CardsViewModel @Inject constructor(
    private val repository: CardsRoomRepository
): ViewModel() {


    private val _results = MutableStateFlow<List<CardsItems>>(emptyList())
    val results: StateFlow<List<CardsItems>> = _results

    private val _resultsForFavorites = MutableStateFlow<List<CardsItems>>(emptyList())
    val resultsForFavorites: StateFlow<List<CardsItems>> = _resultsForFavorites

    private val _resultsForSearch = MutableStateFlow<List<CardsItems>>(emptyList())
    val resultsForSearch: StateFlow<List<CardsItems>> = _resultsForSearch

    private val _switch = mutableStateOf(false)
    var switch: State<Boolean> = _switch
    fun setSwitch(newText: Boolean) {
        _switch.value = newText
    }

    private val _searchQuery = mutableStateOf("")
    val searchQuery: State<String> = _searchQuery
    fun setSearchQuery(newText: String){
        _searchQuery.value = newText
    }

    init {

        getAllLoginsItems()
        getAllFavoriteCardsItems()

    }




    private val _title = mutableStateOf("")
    var title: State<String> = _title
    fun setTitle(newText: String) {
        _title.value = newText
    }

    private val _category = mutableStateOf(0)
    val category: State<Int> = _category
    fun setCategory(newText: Int) {
        _category.value = newText
    }

    private val _cardNumber = mutableStateOf("")
    val cardNumber: State<String> = _cardNumber
    fun setCardNumber(newText: String) {
        _cardNumber.value = newText
    }

    private val _cardHolderName = mutableStateOf("")
    var cardHolderName: State<String> = _cardHolderName
    fun setCardHolderName(newText: String) {
        _cardHolderName.value = newText
    }



    private val _pinNumber = mutableStateOf("")
    var pinNumber: State<String> = _pinNumber
    fun setPinNumber(newText: String) {
        _pinNumber.value = newText
    }

    private val _cvvNumber = mutableStateOf("")
    var cvvNumber: State<String> = _cvvNumber
    fun setCVVNumber(newText: String) {
        _cvvNumber.value = newText
    }

    private val _issueDate = mutableStateOf("")
    var issueDate: State<String> = _issueDate
    fun setIssueDate(newText: String) {
        _issueDate.value = newText
    }

    private val _expiryDate = mutableStateOf("")
    var expiryDate: State<String> = _expiryDate
    fun setExpiryDate(newText: String) {
        _expiryDate.value = newText
    }

    ....


}

@HiltViewModel
class OthersViewModel @Inject constructor(
    private val repository: OthersRoomRepository
) : ViewModel() {

    private val _results = MutableStateFlow<List<OthersItems>>(emptyList())
    val results: StateFlow<List<OthersItems>> = _results

    private val _resultsForFavorites = MutableStateFlow<List<OthersItems>>(emptyList())
    val resultsForFavorites: StateFlow<List<OthersItems>> = _resultsForFavorites

    private val _resultsForSearch = MutableStateFlow<List<OthersItems>>(emptyList())
    val resultsForSearch: StateFlow<List<OthersItems>> = _resultsForSearch

    private val _switch = mutableStateOf(false)
    var switch: State<Boolean> = _switch
    fun setSwitch(newText: Boolean) {
        _switch.value = newText
    }

    private val _searchQuery = mutableStateOf("")
    val searchQuery: State<String> = _searchQuery
    fun setSearchQuery(newText: String) {
        _searchQuery.value = newText
    }

    init {

        getAllOthersItems()
        getAllFavoriteOthersItems()

    }


    private val _title = mutableStateOf("")
    var title: State<String> = _title
    fun setTitle(newText: String) {
        _title.value = newText
    }

    private val _category = mutableStateOf(0)
    val category: State<Int> = _category
    fun setCategory(newText: Int) {
        _category.value = newText
    }

    private val _userName = mutableStateOf("")
    val userName: State<String> = _userName
    fun setUserName(newText: String) {
        _userName.value = newText
    }

    private val _password = mutableStateOf("")
    val password: State<String> = _password
    fun setPassword(newText: String) {
        _password.value = newText
    }

    private val _description = mutableStateOf("")
    val description: State<String> = _description
    fun setDescription(newText: String) {
        _description.value = newText
    }

    private val _macAddress = mutableStateOf("")
    val macAddress: State<String> = _macAddress
    fun setMacAddress(newText: String) {
        _macAddress.value = newText
    }


    ....

}

我认为在您的示例中为每个 属性 创建一个 setter 没有任何意义。当您有一些不仅仅是更新值的逻辑时,它会很有用。

您可以将您的状态移动到单独的 类。只要您将它们作为状态对象,更新它们就会触发重组。

假设您有一个 CardView,它用数字、名称等绘制您的卡片。如果您没有在单独的视图中使用它,那么将您的可组合项拆分为小视图也是一个很好的做法.除了方便将数据拆分成块之外,它还有助于重新配置,并且更易于阅读和开发。

因此将此视图使用的所有数据分组到 CardData:

class CardData {
    val cardNumber = mutableStateOf("")
    val cardHolderName = mutableStateOf("")
    val pinNumber = mutableStateOf("")
    val cvvNumber = mutableStateOf("")
    val issueDate = mutableStateOf("")
    val expiryDate = mutableStateOf("")
}

将其存储在您的视图模型中:

@HiltViewModel
class CardsViewModel @Inject constructor(
    private val repository: CardsRoomRepository
): ViewModel() {
    ...
    val cardData = CardData()
}

并传递给您的视图:

@Composable
fun Screen(viewModel: CardsViewModel() = viewModel()) {
    ...
    CardView(viewModel.cardData)
}

如果您使用这些 setter 传递给文本字段,您可以像这样打开它们:

@Composable
fun CardView(cardData: CardData) {
    val (cardHolderName, cardHolderNameSetter) = cardData.cardHolderName
    TextField(cardHolderName, cardHolderNameSetter)
}