Android Jetpack Compose mit ViewModel

1. Warum ViewModel unverzichtbar ist

Wir haben gelernt, dass RememberSavable den Status speichern kann, wenn der Bildschirm gedreht wird, und die aktuelle Aktivität vom System recycelt wird. ViewModel übernimmt zufällig diese Aufgabe. Warum wird also nicht „rememberSavable“ verwendet, um ViewModel zu ersetzen? In dem Gegenbeispiel, das wir im vorherigen Artikel verwendet haben, können Sie beispielsweise „rememberSavable“ verwenden, um den Status zu speichern, oder Sie können „viewModel“ verwenden, um den Status zu speichern. Dies ist jedoch nur eine Demo. In einem echten Projekt wird die Geschäftslogik dies tun nicht einfach addiert werden. Addition, Subtraktion und Subtraktion sind oft viel komplizierter. Wenn der gesamte Code in einem Stateful Composable platziert wird, sind die Verantwortlichkeiten der Benutzeroberfläche unklar. Schließlich besteht die Hauptverantwortung unseres Composable darin, das anzuzeigen Benutzeroberfläche.

Daher können wir bei komplexer Geschäftslogik den Stateful-Status für die Verwaltung in ViewModel erwähnen, sodass Stateful Composable zu Stateless Composable wird. Durch die Übergabe von Parametern an verschiedene ViewModels kann die spezifische Geschäftslogik ersetzt werden, was die Wiederverwendbarkeit und Testbarkeit erheblich erhöht

2 Verwenden von ViewModel in der Compose-Benutzeroberfläche

In Anlehnung an das vorherige Zählerbeispiel verwenden wir hier die Kombination aus Compose UI und ViewModel, um ein Zählerbeispiel zu implementieren. Der Code lautet wie folgt:

class ComposeCounterAct : ComponentActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContent {
    
    
            MyComposeTheme {
    
    
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
    
    
                    TestCounter()
                }
            }
        }
    }

    @Composable
    fun TestCounter(){
    
    
        val viewModel:ComposeCounterViewModel = viewModel()
        CounterComponent(viewModel.counter.value,viewModel::increment,viewModel::decrement)
    }

    @Composable
    fun CounterComponent(
        counter: Int, // 重组时传入当前需要显示的计数
        onIncrement: () -> Unit,// 回调点击加号的事件
        onDecrement: () -> Unit // 回调单击减号的事件
    ) {
    
    
        Column(modifier = Modifier.padding(16.dp)) {
    
    
            Text(
                "$counter",
                Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center
            )

            Row {
    
    
                Button(
                    onClick = {
    
     onDecrement() },
                    modifier = Modifier.weight(1f)
                ) {
    
    
                    Text("-")
                }

                Spacer(Modifier.width(16.dp))
                Button(
                    onClick = {
    
     onIncrement() },
                    modifier = Modifier.weight(1f)
                ) {
    
    
                    Text("+")
                }
            }
        }
    }
}

class ComposeCounterViewModel:ViewModel(){
    
    
    private val _counter = mutableStateOf(0)
    val counter: State<Int> = _counter

    fun increment(){
    
    
        _counter.value = _counter.value + 1
    }

    fun decrement(){
    
    
      if(_counter.value>0){
    
    
          _counter.value = _counter.value -1
      }
    }
}

Wie im obigen Code gezeigt, entspricht die Verwendung im Wesentlichen Compose UIder ViewModelherkömmlichen Ansicht. In Compose viewModel()ist die Methode eine ComposableMethode. Ihre Funktion besteht darin, über die viewModel()-Methode einen ViewModel-Typ Composablezu erstellen . Dieses ViewModel enthält den Zählerstatus .ViewModel,TestCounterComposeCounterViewModel

注意:在Composable中使用viewModel()方法需要添加依赖: implementation('androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2') ,否则会提示方法找不到。

Die Methode viewModel() hier ruft die ViewModel-Instanz vom neuesten ViewModelStore ab. Dieser ViewModelStore kann eine Aktivität oder ein Fragment sein. Wenn die ViewModel-Instanz nicht vorhanden ist, erstellen Sie eine neue und speichern Sie sie im ViewModelStore. Solange der ViewModelStore nicht zerstört wird, bleibt die darin enthaltene ViewModel-Instanz immer bestehen. Beispielsweise wird das ViewModel, das von Composable in einer Aktivität über die Methode viewModel() erstellt wurde, von der aktuellen Aktivität gehalten. ViewModel ist immer vorhanden, bevor die Aktivität zerstört wird, und jeder Aufruf von viewModel() gibt eine Instanz zurück, sodass wir uns nicht an den Cache erinnern müssen.

注意: 调用viewModel()方法的Composable无法进行预览,若需要进行预览,可以从持有ViewModel的Composable中将需要预览的部分提取成StateLess组件,如文中的CounterComponent组件。

Guess you like

Origin blog.csdn.net/zxj2589/article/details/132850403