API для определения области видимости ViewModel (представлений) — часть Android Jetpack .

Концепции и реализация Jetpack Compose

Область видимости (scope) — ключ к эффективному использованию ViewModel. Каждая ViewModel ограничена объектом, реализующим интерфейс ViewModelStoreOwner . Существует несколько API, позволяющих упростить управление областью видимости ваших ViewModel.

Метод ViewModelProvider.get() позволяет получить экземпляр ViewModel, область видимости которого ограничена любым ViewModelStoreOwner . Для пользователей Kotlin доступны различные функции расширения для наиболее распространенных сценариев использования. Все реализации функций расширения Kotlin используют API ViewModelProvider в качестве основы.

ViewModels ограничены ближайшим ViewModelStoreOwner

Вы можете ограничить область действия ViewModel до Activity, Fragment или до целевого объекта в навигационном графе. Функции расширения viewModels() , предоставляемые библиотеками Activity, Fragment и Navigation, позволяют получить экземпляр ViewModel, область действия которого ограничена ближайшим ViewModelStoreOwner .

Мнения

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

Мнения

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, область действия которых ограничена любым ViewModelStoreOwner.

Функции ComponentActivity.viewModels() и Fragment.viewModels() в системе представлений принимают необязательный параметр ownerProducer , который можно использовать для указания того, к какому ViewModelStoreOwner относится область видимости экземпляра ViewModel. В следующем примере показано, как получить экземпляр ViewModel с областью видимости родительского фрагмента:

Мнения

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

Мнения

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

Получение ViewModel с областью видимости Activity из фрагмента — распространённый сценарий использования. В этом случае можно использовать функцию расширения Views ` activityViewModels() . Если вы не используете Views и Kotlin, вы можете использовать те же API, что и выше, передав в качестве владельца нужный объект.

Мнения

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

Мнения

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, ограниченные областью действия графа навигации.

Графы навигации также являются владельцами хранилища ViewModel. Если вы используете фрагмент навигации , вы можете получить экземпляр ViewModel, привязанный к графу навигации, с помощью функции расширения Views navGraphViewModels(graphId) .

Мнения

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

Мнения

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

Если вы используете Hilt в дополнение к Jetpack Navigation, вы можете использовать API hiltNavGraphViewModels(graphId) следующим образом.

Мнения

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

Мнения

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);
    }
}
{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}