Проблема внедрения HorizontalPager в MotionLayout
У меня есть такой код :
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val list = listOf(R.raw.coffe_big, R.raw.coffe_big, R.raw.coffe_big)
DrinkKitTestMainScreenTheme {
RecipeDetail(list)
}
}
}
}
@OptIn(ExperimentalMotionApi::class, ExperimentalFoundationApi::class)
@Composable
fun RecipeDetail(list: List<Int>) {
val motionState = rememberMotionLayoutState()
val context = LocalContext.current
val motionScene = remember {
context.resources
.openRawResource(R.raw.motion_scene)
.readBytes()
.decodeToString()
}
val pagerState = rememberPagerState(
initialPageOffsetFraction = 0f
) {
return@rememberPagerState list.size
}
val videoUri = rawResourceUri(context, list[0])
val player = remember {
ExoPlayer.Builder(context).build().apply {
val mediaItem = MediaItem.fromUri(videoUri)
setMediaItem(mediaItem)
repeatMode = ExoPlayer.REPEAT_MODE_ONE
prepare()
}
}
LaunchedEffect(motionState) {
snapshotFlow { motionState.currentProgress }.collect { progress ->
player.playWhenReady = true
}
}
DisposableEffect(player) {
onDispose {
player.release()
}
}
HorizontalPager(
state = pagerState,
modifier = Modifier
.layoutId("HorizontalPager")
.fillMaxSize()
) { page ->
MotionLayout(
motionScene = MotionScene(content = motionScene),
motionLayoutState = motionState,
modifier = Modifier
.fillMaxSize()
.background(Color.Transparent)
.pointerInput(Unit) {
detectTapGestures(onTap = {})
}
) {
AndroidView(
modifier = Modifier.layoutId("headerImage"),
factory = {
PlayerView(it).apply {
this.player = player
useController = false
resizeMode =
AspectRatioFrameLayout.RESIZE_MODE_FILL
}
}
)
Box(
modifier = Modifier
.fillMaxHeight()
.background(
White,
shape = RoundedCornerShape(topStart = 10.dp, topEnd = 10.dp)
)
.layoutId("contentBg")
)
Text(
color = Color.White,
text = "Fresh Strawberry Cake", fontSize = 22.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold, modifier = Modifier
.layoutId("title_price")
.fillMaxWidth()
.padding(10.dp)
)
Text(
text = list[page].toString(), fontSize = 22.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold, modifier = Modifier
.layoutId("title")
.fillMaxWidth()
.padding(10.dp)
)
Divider(
Modifier
.layoutId("titleDivider")
.fillMaxWidth()
.padding(horizontal = 34.dp)
)
Text(
text = "by John Kanell", fontSize = 16.sp,
textAlign = TextAlign.Center,
color = Gray, fontStyle = FontStyle.Italic,
modifier = Modifier
.layoutId("subTitle")
.fillMaxWidth()
.padding(6.dp)
)
Text(
modifier = Modifier
.layoutId("date")
.fillMaxWidth()
.padding(6.dp),
text = "September, 2022", fontSize = 16.sp,
textAlign = TextAlign.Center,
color = Gray
)
Row(
modifier = Modifier
.layoutId("actions")
.background(Color.DarkGray),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
) {
Text(
text = "texttttttt",
modifier = Modifier
.fillMaxHeight()
.layoutId("text")
.padding(horizontal = 16.dp),
fontSize = 12.sp,
)
}
}
}
}
В данный момент скрол-свайп в HorizontalPager просто не работает. я также пропобовал поместить HorizontalPager внутрь MotionLayout, но тогда весь контент кроме Android View пропадают :
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val list = listOf(R.raw.coffe_big, R.raw.coffe_big, R.raw.coffe_big)
DrinkKitTestMainScreenTheme {
RecipeDetail(list)
}
}
}
}
@OptIn(ExperimentalMotionApi::class, ExperimentalFoundationApi::class)
@Composable
fun RecipeDetail(list: List<Int>) {
val motionState = rememberMotionLayoutState()
val context = LocalContext.current
val motionScene = remember {
context.resources
.openRawResource(R.raw.motion_scene)
.readBytes()
.decodeToString()
}
val pagerState = rememberPagerState(
initialPageOffsetFraction = 0f
) {
return@rememberPagerState list.size
}
val videoUri = rawResourceUri(context, list[0])
val player = remember {
ExoPlayer.Builder(context).build().apply {
val mediaItem = MediaItem.fromUri(videoUri)
setMediaItem(mediaItem)
repeatMode = ExoPlayer.REPEAT_MODE_ONE
prepare()
}
}
LaunchedEffect(motionState) {
snapshotFlow { motionState.currentProgress }.collect { progress ->
player.playWhenReady = true
}
}
DisposableEffect(player) {
onDispose {
player.release()
}
}
MotionLayout(
motionScene = MotionScene(content = motionScene),
motionLayoutState = motionState,
modifier = Modifier
.fillMaxSize()
.background(Color.Transparent)
.pointerInput(Unit) {
detectTapGestures(onTap = {})
}
) {
HorizontalPager(
state = pagerState,
modifier = Modifier
.layoutId("HorizontalPager")
.fillMaxSize()
) { page ->
AndroidView(
modifier = Modifier.layoutId("headerImage"),
factory = {
PlayerView(it).apply {
this.player = player
useController = false
resizeMode =
AspectRatioFrameLayout.RESIZE_MODE_FILL
}
}
)
Box(
modifier = Modifier
.fillMaxHeight()
.background(
White,
shape = RoundedCornerShape(topStart = 10.dp, topEnd = 10.dp)
)
.layoutId("contentBg")
)
Text(
color = Color.White,
text = "Fresh Strawberry Cake", fontSize = 22.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold, modifier = Modifier
.layoutId("title_price")
.fillMaxWidth()
.padding(10.dp)
)
Text(
text = list[page].toString(), fontSize = 22.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold, modifier = Modifier
.layoutId("title")
.fillMaxWidth()
.padding(10.dp)
)
Divider(
Modifier
.layoutId("titleDivider")
.fillMaxWidth()
.padding(horizontal = 34.dp)
)
Text(
text = "by John Kanell", fontSize = 16.sp,
textAlign = TextAlign.Center,
color = Gray, fontStyle = FontStyle.Italic,
modifier = Modifier
.layoutId("subTitle")
.fillMaxWidth()
.padding(6.dp)
)
Text(
modifier = Modifier
.layoutId("date")
.fillMaxWidth()
.padding(6.dp),
text = "September, 2022", fontSize = 16.sp,
textAlign = TextAlign.Center,
color = Gray
)
Row(
modifier = Modifier
.layoutId("actions")
.background(Color.DarkGray),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
) {
Text(
text = "texttttttt",
modifier = Modifier
.fillMaxHeight()
.layoutId("text")
.padding(horizontal = 16.dp),
fontSize = 12.sp,
)
}
}
}
}
и также после этого при попытки начать анимацию выходит java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.constraintlayout.core.state.Transition$WidgetState.interpolate(int, int, float, androidx.constraintlayout.core.state.Transition)' on a null object reference
я также пытался в motion_scene внедрить HorizontalPager :
{
"ConstraintSets": {
"start": {
"headerImage": {
"width": "spread",
"height": "spread",
"top": [
"parent",
"top",
0
],
"bottom": [
"parent",
"bottom",
0
],
"start": [
"parent",
"start",
0
],
"end": [
"parent",
"end",
0
],
"translationY": 0,
"alpha": 1
},
"HorizontalPager": {
"width": "spread",
"height": "wrap",
"top": [
"parent",
"top",
0
],
"start": [
"parent",
"start",
0
],
"end": [
"parent",
"end",
0
]
},
"title_price": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"parent",
"top",
550
],
"translationY": 0,
"alpha": 1
},
"title": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"parent",
"top",
650
]
},
"titleDivider": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"title",
"bottom"
]
},
"subTitle": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"titleDivider",
"bottom"
]
},
"subTitleDivider": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"subTitle",
"bottom"
]
},
"contentBg": {
"width": "spread",
"height": "spread",
"start": [
"parent",
"start",
16
],
"end": [
"parent",
"end",
16
],
"top": [
"parent",
"top",
650
],
"bottom": [
"parent",
"bottom"
]
},
"date": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"subTitleDivider",
"bottom"
]
},
"actions": {
"width": "spread",
"height": 50,
"start": [
"parent",
"start",
16
],
"end": [
"parent",
"end",
16
],
"top": [
"date",
"bottom"
]
},
"text": {
"width": "spread",
"height": "spread",
"start": [
"parent",
"start",
16
],
"end": [
"parent",
"end",
16
],
"top": [
"actions",
"bottom",
16
],
"bottom": [
"parent",
"bottom"
]
}
},
"end": {
"headerImage": {
"width": "spread",
"height": 750,
"top": [
"parent",
"top",
0
],
"start": [
"parent",
"start",
0
],
"end": [
"parent",
"end",
0
],
"translationY": -250,
"alpha": 0.3
},
"HorizontalPager": {
"width": "spread",
"height": "wrap",
"top": [
"parent",
"top",
0
],
"start": [
"parent",
"start",
0
],
"end": [
"parent",
"end",
0
]
},
"contentBg": {
"width": "spread",
"height": "spread",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"parent",
"top"
],
"bottom": [
"parent",
"bottom"
]
},
"title": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"parent",
"top",
6
]
},
"title_price": {
"width": "spread",
"height": 750,
"top": [
"parent",
"top",
0
],
"start": [
"parent",
"start",
0
],
"end": [
"parent",
"end",
0
],
"translationY": -250,
"alpha": 0.3
},
"titleDivider": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start",
34
],
"end": [
"parent",
"end",
34
],
"top": [
"title",
"bottom"
]
},
"subTitle": {
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"titleDivider",
"bottom"
]
},
"subTitleDivider": {
"visibility": "gone",
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"subTitle",
"bottom"
]
},
"date": {
"visibility": "gone",
"width": "spread",
"height": "wrap",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"subTitleDivider",
"bottom"
]
},
"actions": {
"width": "spread",
"height": 70,
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"subTitle",
"bottom"
]
},
"text": {
"width": "spread",
"height": "spread",
"start": [
"parent",
"start"
],
"end": [
"parent",
"end"
],
"top": [
"actions",
"bottom",
16
],
"bottom": [
"parent",
"bottom"
]
}
}
},
"Transitions": {
"default": {
"from": "start",
"to": "end",
"onSwipe": {
"anchor": "contentBg",
"direction": "up",
"side": "top"
}
}
}
}
но что и с HorizontalPager, что и без HorizontalPager в motion_scene ничего не поменялось , также не видно элемнеты и выходит ошибка