APIs für den ViewModel-Bereich (Ansichten)   Teil von Android Jetpack.

Konzepte und Jetpack Compose-Implementierung

Der Bereich ist entscheidend für die effektive Verwendung von ViewModels. Jedes ViewModel ist auf ein Objekt beschränkt, das die ViewModelStoreOwner Schnittstelle implementiert. Es gibt mehrere APIs, mit denen Sie den Bereich Ihrer ViewModels einfacher verwalten können.

Mit der Methode ViewModelProvider.get() können Sie eine Instanz eines ViewModels abrufen, das auf einen beliebigen ViewModelStoreOwner beschränkt ist. Für Kotlin-Nutzer sind verschiedene Erweiterungsfunktionen für die häufigsten Anwendungsfälle verfügbar. Alle Implementierungen von Kotlin-Erweiterungsfunktionen verwenden im Hintergrund die ViewModelProvider API.

ViewModels, die auf den nächstgelegenen ViewModelStoreOwner beschränkt sind

Sie können ein ViewModel auf eine Aktivität, ein Fragment oder ein Ziel eines Navigationsdiagramms beschränken. Mit den viewModels() Erweiterungsfunktionen, die von den Bibliotheken für Aktivitäten, Fragmente und Navigation bereitgestellt werden, können Sie eine Instanz des ViewModels abrufen, das auf den nächstgelegenen ViewModelStoreOwner beschränkt ist.

Aufrufe

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

Aufrufe

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, die auf einen beliebigen ViewModelStoreOwner beschränkt sind

Die Funktionen ComponentActivity.viewModels() und Fragment.viewModels() im Ansichtssystem verwenden einen optionalen Parameter ownerProducer, mit dem Sie angeben können, auf welchen ViewModelStoreOwner die Instanz des ViewModels beschränkt ist. Im folgenden Beispiel wird gezeigt, wie Sie eine Instanz eines ViewModels abrufen, das auf das übergeordnete Fragment beschränkt ist:

Aufrufe

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

Aufrufe

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

Ein häufiger Anwendungsfall ist das Abrufen eines auf eine Aktivität beschränkten ViewModels aus einem Fragment. Dabei können Sie die Erweiterungsfunktion activityViewModels() für Ansichten verwenden. Wenn Sie keine Ansichten und kein Kotlin verwenden, können Sie dieselben APIs wie oben verwenden und den richtigen Inhaber übergeben.

Aufrufe

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

Aufrufe

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, die auf das Navigationsdiagramm beschränkt sind

Navigationsdiagramme sind auch ViewModel-Speicherinhaber. Wenn Sie ein Navigationsfragment verwenden, können Sie mit der navGraphViewModels(graphId) Erweiterungsfunktion für Ansichten eine Instanz eines Viewmodels abrufen, das auf ein Navigationsdiagramm beschränkt ist.

Aufrufe

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

Aufrufe

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

Wenn Sie zusätzlich zu Jetpack Navigation auch Hilt verwenden, können Sie die hiltNavGraphViewModels(graphId) API wie folgt verwenden.

Aufrufe

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

Aufrufe

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