Общие элементы с помощью Navigation Compose

Чтобы использовать общие элементы с зависимостью Navigation-Compose , вы можете использовать те же концепции, которые были показаны ранее: используйте Modifier.sharedElement() , который принимает AnimatedVisibilityScope в качестве параметра. Вы можете использовать это, чтобы решить, что и когда должно быть видно.

Рисунок 1. Создание навигации с использованием общих элементов

Ниже приведен пример использования navigation-compose с общими элементами:

@Preview
@Composable
fun SharedElement_PredictiveBack() {
   
SharedTransitionLayout {
       
val navController = rememberNavController()
       
NavHost(
            navController
= navController,
            startDestination
= "home"
       
) {
            composable
("home") {
               
HomeScreen(
                    navController
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
            composable
(
               
"details/{item}",
                arguments
= listOf(navArgument("item") { type = NavType.IntType })
           
) { backStackEntry ->
               
val id = backStackEntry.arguments?.getInt("item")
               
val snack = listSnacks[id!!]
               
DetailsScreen(
                    navController
,
                    id
,
                    snack
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
       
}
   
}
}

@Composable
private fun DetailsScreen(
    navController
: NavHostController,
    id
: Int,
    snack
: Snack,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
    with
(sharedTransitionScope) {
       
Column(
           
Modifier
               
.fillMaxSize()
               
.clickable {
                    navController
.navigate("home")
               
}
       
) {
           
Image(
                painterResource
(id = snack.image),
                contentDescription
= snack.description,
                contentScale
= ContentScale.Crop,
                modifier
= Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "image-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.aspectRatio(1f)
                   
.fillMaxWidth()
           
)
           
Text(
                snack
.name, fontSize = 18.sp,
                modifier
=
               
Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "text-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.fillMaxWidth()
           
)
       
}
   
}
}

@Composable
private fun HomeScreen(
    navController
: NavHostController,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
   
LazyColumn(
        modifier
= Modifier
           
.fillMaxSize()
           
.padding(8.dp),
        verticalArrangement
= Arrangement.spacedBy(8.dp)
   
) {
        itemsIndexed
(listSnacks) { index, item ->
           
Row(
               
Modifier.clickable {
                    navController
.navigate("details/$index")
               
}
           
) {
               
Spacer(modifier = Modifier.width(8.dp))
                with
(sharedTransitionScope) {
                   
Image(
                        painterResource
(id = item.image),
                        contentDescription
= item.description,
                        contentScale
= ContentScale.Crop,
                        modifier
= Modifier
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "image-$index"),
                                animatedVisibilityScope
= animatedContentScope
                           
)
                           
.size(100.dp)
                   
)
                   
Spacer(modifier = Modifier.width(8.dp))
                   
Text(
                        item
.name, fontSize = 18.sp,
                        modifier
= Modifier
                           
.align(Alignment.CenterVertically)
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "text-$index"),
                                animatedVisibilityScope
= animatedContentScope,
                           
)
                   
)
               
}
           
}
       
}
   
}
}

data class Snack(
   
val name: String,
   
val description: String,
   
@DrawableRes val image: Int
)

Прогнозируемый ответ с общими элементами

Если вы хотите использовать предиктивную обратную связь с общими элементами, убедитесь, что вы используете последнюю зависимость navigation-compose , используя фрагмент из предыдущего раздела.

dependencies {
   
def nav_version = "2.8.0-beta02"

    implementation
"androidx.navigation:navigation-compose:$nav_version"
}

Добавьте android:enableOnBackInvokedCallback="true" в файл AndroidManifest.xml , чтобы включить функцию прогнозирования:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
   
<uses-permission android:name="android.permission.INTERNET" />
   
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
       
android:maxSdkVersion="28" />

   
<application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:roundIcon="@mipmap/ic_launcher_round"
       
android:supportsRtl="true"
       
android:enableOnBackInvokedCallback="true"
       
android:theme="@style/Theme.Snippets">
Рис. 2. Навигация по созданию текста с функцией прогнозирования назад
,

Чтобы использовать общие элементы с зависимостью Navigation-Compose , вы можете использовать те же концепции, которые были показаны ранее: используйте Modifier.sharedElement() , который принимает AnimatedVisibilityScope в качестве параметра. Вы можете использовать это, чтобы решить, что и когда должно быть видно.

Рисунок 1. Создание навигации с использованием общих элементов

Ниже приведен пример использования navigation-compose с общими элементами:

@Preview
@Composable
fun SharedElement_PredictiveBack() {
   
SharedTransitionLayout {
       
val navController = rememberNavController()
       
NavHost(
            navController
= navController,
            startDestination
= "home"
       
) {
            composable
("home") {
               
HomeScreen(
                    navController
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
            composable
(
               
"details/{item}",
                arguments
= listOf(navArgument("item") { type = NavType.IntType })
           
) { backStackEntry ->
               
val id = backStackEntry.arguments?.getInt("item")
               
val snack = listSnacks[id!!]
               
DetailsScreen(
                    navController
,
                    id
,
                    snack
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
       
}
   
}
}

@Composable
private fun DetailsScreen(
    navController
: NavHostController,
    id
: Int,
    snack
: Snack,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
    with
(sharedTransitionScope) {
       
Column(
           
Modifier
               
.fillMaxSize()
               
.clickable {
                    navController
.navigate("home")
               
}
       
) {
           
Image(
                painterResource
(id = snack.image),
                contentDescription
= snack.description,
                contentScale
= ContentScale.Crop,
                modifier
= Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "image-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.aspectRatio(1f)
                   
.fillMaxWidth()
           
)
           
Text(
                snack
.name, fontSize = 18.sp,
                modifier
=
               
Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "text-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.fillMaxWidth()
           
)
       
}
   
}
}

@Composable
private fun HomeScreen(
    navController
: NavHostController,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
   
LazyColumn(
        modifier
= Modifier
           
.fillMaxSize()
           
.padding(8.dp),
        verticalArrangement
= Arrangement.spacedBy(8.dp)
   
) {
        itemsIndexed
(listSnacks) { index, item ->
           
Row(
               
Modifier.clickable {
                    navController
.navigate("details/$index")
               
}
           
) {
               
Spacer(modifier = Modifier.width(8.dp))
                with
(sharedTransitionScope) {
                   
Image(
                        painterResource
(id = item.image),
                        contentDescription
= item.description,
                        contentScale
= ContentScale.Crop,
                        modifier
= Modifier
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "image-$index"),
                                animatedVisibilityScope
= animatedContentScope
                           
)
                           
.size(100.dp)
                   
)
                   
Spacer(modifier = Modifier.width(8.dp))
                   
Text(
                        item
.name, fontSize = 18.sp,
                        modifier
= Modifier
                           
.align(Alignment.CenterVertically)
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "text-$index"),
                                animatedVisibilityScope
= animatedContentScope,
                           
)
                   
)
               
}
           
}
       
}
   
}
}

data class Snack(
   
val name: String,
   
val description: String,
   
@DrawableRes val image: Int
)

Прогнозируемый ответ с общими элементами

Если вы хотите использовать предиктивную обратную связь с общими элементами, убедитесь, что вы используете последнюю зависимость navigation-compose , используя фрагмент из предыдущего раздела.

dependencies {
   
def nav_version = "2.8.0-beta02"

    implementation
"androidx.navigation:navigation-compose:$nav_version"
}

Добавьте android:enableOnBackInvokedCallback="true" в файл AndroidManifest.xml , чтобы включить функцию прогнозирования:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
   
<uses-permission android:name="android.permission.INTERNET" />
   
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
       
android:maxSdkVersion="28" />

   
<application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:roundIcon="@mipmap/ic_launcher_round"
       
android:supportsRtl="true"
       
android:enableOnBackInvokedCallback="true"
       
android:theme="@style/Theme.Snippets">
Рис. 2. Навигация по созданию текста с функцией прогнозирования назад
,

Чтобы использовать общие элементы с зависимостью Navigation-Compose , вы можете использовать те же концепции, которые были показаны ранее: используйте Modifier.sharedElement() , который принимает AnimatedVisibilityScope в качестве параметра. Вы можете использовать это, чтобы решить, что и когда должно быть видно.

Рисунок 1. Создание навигации с использованием общих элементов

Ниже приведен пример использования navigation-compose с общими элементами:

@Preview
@Composable
fun SharedElement_PredictiveBack() {
   
SharedTransitionLayout {
       
val navController = rememberNavController()
       
NavHost(
            navController
= navController,
            startDestination
= "home"
       
) {
            composable
("home") {
               
HomeScreen(
                    navController
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
            composable
(
               
"details/{item}",
                arguments
= listOf(navArgument("item") { type = NavType.IntType })
           
) { backStackEntry ->
               
val id = backStackEntry.arguments?.getInt("item")
               
val snack = listSnacks[id!!]
               
DetailsScreen(
                    navController
,
                    id
,
                    snack
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
       
}
   
}
}

@Composable
private fun DetailsScreen(
    navController
: NavHostController,
    id
: Int,
    snack
: Snack,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
    with
(sharedTransitionScope) {
       
Column(
           
Modifier
               
.fillMaxSize()
               
.clickable {
                    navController
.navigate("home")
               
}
       
) {
           
Image(
                painterResource
(id = snack.image),
                contentDescription
= snack.description,
                contentScale
= ContentScale.Crop,
                modifier
= Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "image-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.aspectRatio(1f)
                   
.fillMaxWidth()
           
)
           
Text(
                snack
.name, fontSize = 18.sp,
                modifier
=
               
Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "text-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.fillMaxWidth()
           
)
       
}
   
}
}

@Composable
private fun HomeScreen(
    navController
: NavHostController,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
   
LazyColumn(
        modifier
= Modifier
           
.fillMaxSize()
           
.padding(8.dp),
        verticalArrangement
= Arrangement.spacedBy(8.dp)
   
) {
        itemsIndexed
(listSnacks) { index, item ->
           
Row(
               
Modifier.clickable {
                    navController
.navigate("details/$index")
               
}
           
) {
               
Spacer(modifier = Modifier.width(8.dp))
                with
(sharedTransitionScope) {
                   
Image(
                        painterResource
(id = item.image),
                        contentDescription
= item.description,
                        contentScale
= ContentScale.Crop,
                        modifier
= Modifier
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "image-$index"),
                                animatedVisibilityScope
= animatedContentScope
                           
)
                           
.size(100.dp)
                   
)
                   
Spacer(modifier = Modifier.width(8.dp))
                   
Text(
                        item
.name, fontSize = 18.sp,
                        modifier
= Modifier
                           
.align(Alignment.CenterVertically)
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "text-$index"),
                                animatedVisibilityScope
= animatedContentScope,
                           
)
                   
)
               
}
           
}
       
}
   
}
}

data class Snack(
   
val name: String,
   
val description: String,
   
@DrawableRes val image: Int
)

Прогнозируемый ответ с общими элементами

Если вы хотите использовать предиктивную обратную связь с общими элементами, убедитесь, что вы используете последнюю зависимость navigation-compose , используя фрагмент из предыдущего раздела.

dependencies {
   
def nav_version = "2.8.0-beta02"

    implementation
"androidx.navigation:navigation-compose:$nav_version"
}

Добавьте android:enableOnBackInvokedCallback="true" в файл AndroidManifest.xml , чтобы включить функцию прогнозирования:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
   
<uses-permission android:name="android.permission.INTERNET" />
   
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
       
android:maxSdkVersion="28" />

   
<application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:roundIcon="@mipmap/ic_launcher_round"
       
android:supportsRtl="true"
       
android:enableOnBackInvokedCallback="true"
       
android:theme="@style/Theme.Snippets">
Рис. 2. Навигация по созданию текста с функцией прогнозирования назад
,

Чтобы использовать общие элементы с зависимостью Navigation-Compose , вы можете использовать те же концепции, которые были показаны ранее: используйте Modifier.sharedElement() , который принимает AnimatedVisibilityScope в качестве параметра. Вы можете использовать это, чтобы решить, что и когда должно быть видно.

Рисунок 1. Создание навигации с использованием общих элементов

Ниже приведен пример использования navigation-compose с общими элементами:

@Preview
@Composable
fun SharedElement_PredictiveBack() {
   
SharedTransitionLayout {
       
val navController = rememberNavController()
       
NavHost(
            navController
= navController,
            startDestination
= "home"
       
) {
            composable
("home") {
               
HomeScreen(
                    navController
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
            composable
(
               
"details/{item}",
                arguments
= listOf(navArgument("item") { type = NavType.IntType })
           
) { backStackEntry ->
               
val id = backStackEntry.arguments?.getInt("item")
               
val snack = listSnacks[id!!]
               
DetailsScreen(
                    navController
,
                    id
,
                    snack
,
                   
this@SharedTransitionLayout,
                   
this@composable
               
)
           
}
       
}
   
}
}

@Composable
private fun DetailsScreen(
    navController
: NavHostController,
    id
: Int,
    snack
: Snack,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
    with
(sharedTransitionScope) {
       
Column(
           
Modifier
               
.fillMaxSize()
               
.clickable {
                    navController
.navigate("home")
               
}
       
) {
           
Image(
                painterResource
(id = snack.image),
                contentDescription
= snack.description,
                contentScale
= ContentScale.Crop,
                modifier
= Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "image-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.aspectRatio(1f)
                   
.fillMaxWidth()
           
)
           
Text(
                snack
.name, fontSize = 18.sp,
                modifier
=
               
Modifier
                   
.sharedElement(
                        sharedTransitionScope
.rememberSharedContentState(key = "text-$id"),
                        animatedVisibilityScope
= animatedContentScope
                   
)
                   
.fillMaxWidth()
           
)
       
}
   
}
}

@Composable
private fun HomeScreen(
    navController
: NavHostController,
    sharedTransitionScope
: SharedTransitionScope,
    animatedContentScope
: AnimatedContentScope
) {
   
LazyColumn(
        modifier
= Modifier
           
.fillMaxSize()
           
.padding(8.dp),
        verticalArrangement
= Arrangement.spacedBy(8.dp)
   
) {
        itemsIndexed
(listSnacks) { index, item ->
           
Row(
               
Modifier.clickable {
                    navController
.navigate("details/$index")
               
}
           
) {
               
Spacer(modifier = Modifier.width(8.dp))
                with
(sharedTransitionScope) {
                   
Image(
                        painterResource
(id = item.image),
                        contentDescription
= item.description,
                        contentScale
= ContentScale.Crop,
                        modifier
= Modifier
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "image-$index"),
                                animatedVisibilityScope
= animatedContentScope
                           
)
                           
.size(100.dp)
                   
)
                   
Spacer(modifier = Modifier.width(8.dp))
                   
Text(
                        item
.name, fontSize = 18.sp,
                        modifier
= Modifier
                           
.align(Alignment.CenterVertically)
                           
.sharedElement(
                                sharedTransitionScope
.rememberSharedContentState(key = "text-$index"),
                                animatedVisibilityScope
= animatedContentScope,
                           
)
                   
)
               
}
           
}
       
}
   
}
}

data class Snack(
   
val name: String,
   
val description: String,
   
@DrawableRes val image: Int
)

Прогнозируемый ответ с общими элементами

Если вы хотите использовать предиктивную обратную связь с общими элементами, убедитесь, что вы используете последнюю зависимость navigation-compose , используя фрагмент из предыдущего раздела.

dependencies {
   
def nav_version = "2.8.0-beta02"

    implementation
"androidx.navigation:navigation-compose:$nav_version"
}

Добавьте android:enableOnBackInvokedCallback="true" в файл AndroidManifest.xml , чтобы включить функцию прогнозирования:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
   
<uses-permission android:name="android.permission.INTERNET" />
   
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
       
android:maxSdkVersion="28" />

   
<application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:roundIcon="@mipmap/ic_launcher_round"
       
android:supportsRtl="true"
       
android:enableOnBackInvokedCallback="true"
       
android:theme="@style/Theme.Snippets">
Рис. 2. Навигация по созданию текста с функцией прогнозирования назад