API di definizione dell'ambito di ViewModel (visualizzazioni)   Parte di Android Jetpack.

Concetti e implementazione di Jetpack Compose

L'ambito è fondamentale per utilizzare i ViewModel in modo efficace. Ogni ViewModel è associato a un oggetto che implementa l'interfaccia ViewModelStoreOwner. Esistono diverse API che ti consentono di gestire più facilmente l'ambito dei tuoi ViewModel.

Il metodo ViewModelProvider.get() consente di ottenere un'istanza di un ViewModel con ambito qualsiasi ViewModelStoreOwner. Per gli utenti Kotlin, sono disponibili diverse funzioni di estensione per i casi d'uso più comuni. Tutte le implementazioni delle funzioni di estensione Kotlin utilizzano l'API ViewModelProvider.

ViewModel con ambito definito sul ViewModelStoreOwner più vicino

Puoi definire l'ambito di un ViewModel in un'attività, un fragment o una destinazione di un grafico di navigazione. Le funzioni di estensione viewModels() fornite dalle librerie Activity, Fragment e Navigation consentono di ottenere un'istanza di ViewModel con ambito impostato sul ViewModelStoreOwner più vicino.

Visualizzazioni

import androidx.activity.viewModels

class MyActivity : AppCompatActivity() {
    // ViewModel API available in activity.activity-ktx
    // The ViewModel is scoped to `this` Activity
    val viewModel: MyViewModel by viewModels()
}

import androidx.fragment.app.viewModels

class MyFragment : Fragment() {
    // ViewModel API available in fragment.fragment-ktx
    // The ViewModel is scoped to `this` Fragment
    val viewModel: MyViewModel by viewModels()
}

Visualizzazioni

import androidx.lifecycle.ViewModelProvider;

public class MyActivity extends AppCompatActivity {
    // The ViewModel is scoped to `this` Activity
    MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
}

public class MyFragment extends Fragment {
    // The ViewModel is scoped to `this` Fragment
    MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
}

ViewModel con ambito qualsiasi ViewModelStoreOwner

Le funzioni ComponentActivity.viewModels() e Fragment.viewModels() nel sistema View accettano un parametro ownerProducer facoltativo che puoi utilizzare per specificare a quale ViewModelStoreOwner è associata l'istanza di ViewModel. Il seguente esempio mostra come ottenere un'istanza di un ViewModel con ambito nel fragment padre:

Visualizzazioni

import androidx.fragment.app.viewModels

class MyFragment : Fragment() {

    // ViewModel API available in fragment.fragment-ktx
    // The ViewModel is scoped to the parent of `this` Fragment
    val viewModel: SharedViewModel by viewModels(
        ownerProducer = { requireParentFragment() }
    )
}

Visualizzazioni

import androidx.lifecycle.ViewModelProvider;

public class MyFragment extends Fragment {

    SharedViewModel viewModel;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // The ViewModel is scoped to the parent of `this` Fragment
        viewModel = new ViewModelProvider(requireParentFragment())
            .get(SharedViewModel.class);
    }
}

Ottenere un ViewModel con ambito attività da un fragment è un caso d'uso comune. In questo caso, puoi utilizzare la funzione di estensione activityViewModels(). Se non utilizzi Views e Kotlin, puoi utilizzare le stesse API indicate sopra passando il proprietario corretto.

Visualizzazioni

import androidx.fragment.app.activityViewModels

class MyFragment : Fragment() {

    // ViewModel API available in fragment.fragment-ktx
    // The ViewModel is scoped to the host Activity
    val viewModel: SharedViewModel by activityViewModels()
}

Visualizzazioni

import androidx.lifecycle.ViewModelProvider;

public class MyFragment extends Fragment {

    SharedViewModel viewModel;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // The ViewModel is scoped to the host Activity
        viewModel = new ViewModelProvider(requireActivity())
            .get(SharedViewModel.class);
    }
}

ViewModel con ambito nel grafico di navigazione

I grafici di navigazione sono anche proprietari dell'archivio ViewModel. Se utilizzi Navigation Fragment, puoi ottenere un'istanza di un ViewModel con ambito in un grafico di navigazione con la funzione di estensione navGraphViewModels(graphId) Views.

Visualizzazioni

import androidx.navigation.navGraphViewModels

class MyFragment : Fragment() {

    // ViewModel API available in navigation.navigation-fragment
    // The ViewModel is scoped to the `nav_graph` Navigation graph
    val viewModel: SharedViewModel by navGraphViewModels(R.id.nav_graph)

    // Equivalent navGraphViewModels code using the viewModels API
    val viewModel: SharedViewModel by viewModels(
        { findNavController().getBackStackEntry(R.id.nav_graph) }
    )
}

Visualizzazioni

import androidx.lifecycle.ViewModelProvider;

public class MyFragment extends Fragment {

    SharedViewModel viewModel;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        NavController navController = NavHostFragment.findNavController(this);
        NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph);

        // The ViewModel is scoped to the `nav_graph` Navigation graph
        viewModel = new ViewModelProvider(backStackEntry).get(SharedViewModel.class);
    }
}

Se utilizzi Hilt oltre a Jetpack Navigation, puoi utilizzare l'API hiltNavGraphViewModels(graphId) come segue.

Visualizzazioni

import androidx.hilt.navigation.fragment.hiltNavGraphViewModels

class MyFragment : Fragment() {

    // ViewModel API available in hilt.hilt-navigation-fragment
    // The ViewModel is scoped to the `nav_graph` Navigation graph
    // and is provided using the Hilt-generated ViewModel factory
    val viewModel: SharedViewModel by hiltNavGraphViewModels(R.id.nav_graph)
}

Visualizzazioni

import androidx.hilt.navigation.HiltViewModelFactory;
import androidx.lifecycle.ViewModelProvider;

public class MyFragment extends Fragment {

    SharedViewModel viewModel;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        NavController navController = NavHostFragment.findNavController(this);
        NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph);

        // The ViewModel is scoped to the `nav_graph` Navigation graph
        // and is provided using the Hilt-generated ViewModel factory
        viewModel = new ViewModelProvider(
            backStackEntry,
            HiltViewModelFactory.create(getContext(), backStackEntry)
        ).get(SharedViewModel.class);
    }
}