API de champ d'application ViewModel (Views)   Inclus dans Android Jetpack.

Concepts et implémentation de Jetpack Compose

Le champ d'application est essentiel pour utiliser efficacement des ViewModels. Chaque ViewModel s'applique à un objet qui implémente l'interface ViewModelStoreOwner. Plusieurs API vous permettent de gérer plus facilement le champ d'application de vos ViewModels.

La méthode ViewModelProvider.get() vous permet d'obtenir une instance d'un ViewModel limité à n'importe quel ViewModelStoreOwner. Pour les utilisateurs de Kotlin, différentes fonctions d'extension sont disponibles pour les cas d'utilisation les plus courants. Toutes les implémentations de fonctions d'extension Kotlin utilisent l'API ViewModelProvider.

ViewModels limités au ViewModelStoreOwner le plus proche

Vous pouvez limiter le champ d'application d'un ViewModel à une activité, à un fragment ou à la destination d'un graphique de navigation. Les fonctions d'extension fournies par les bibliothèques Activity, Fragment et Navigation vous permettent d'obtenir une instance de ViewModel limitée au ViewModelStoreOwner le plus proche.viewModels()

Views

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()
}

Views

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);
}

ViewModels limités à un ViewModelStoreOwner

Les fonctions ComponentActivity.viewModels() et Fragment.viewModels() du système View acceptent le paramètre facultatif ownerProducer, que vous pouvez utiliser pour spécifier le ViewModelStoreOwner auquel l'instance du ViewModel s'applique. L'exemple suivant montre comment obtenir une instance d'un ViewModel limité au fragment parent :

Views

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() }
    )
}

Views

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);
    }
}

L'obtention d'un ViewModel limité à l'activité à partir d'un fragment est un cas d'utilisation courant. Dans ce cas, vous pouvez utiliser la fonction d'extension activityViewModels() Views Si vous n'utilisez pas Views et Kotlin, vous pouvez utiliser les mêmes API que ci-dessus, en transmettant le bon propriétaire.

Views

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()
}

Views

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);
    }
}

ViewModels limités au graphique de navigation

Les graphiques de navigation sont également propriétaires de magasin ViewModel. Si vous utilisez Navigation Fragment, vous pouvez obtenir une instance d'un ViewModel limité à un graphique de navigation à l'aide de la fonction d'extension Views navGraphViewModels(graphId).

Views

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) }
    )
}

Views

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);
    }
}

Si vous utilisez Hilt en plus de Jetpack Navigation, vous pouvez utiliser l' hiltNavGraphViewModels(graphId) API comme suit.

Views

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)
}

Views

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);
    }
}