如何在Compose中优化AndroidView与懒惰列表的布局组合
我有两个问题,浏览lazycolumn
或verticalpager
androidview
填充整个屏幕,因为屏幕上的项目滞后于屏幕和滚动行为。几毫秒以及重叠的物品。在我的代码中androidView
创建Playerview
,我还尝试用playerview
textview
来检查可能问题。与Playerview
本身。我似乎无法完全找到问题的根源,也许使用androidView
或实现verticalpager
本身,还是因为它填充了整个屏幕?
viewScreen
@OptIn(ExperimentalPagerApi::class)
@Composable
fun VideoScreen() {
val pagerState = rememberPagerState()
Box {
VerticalPager(
count = videos.size,
state = pagerState,
horizontalAlignment = Alignment.CenterHorizontally,
itemSpacing = 10.dp
) { index ->
VideoPlayer(
vid = videos[index],
shouldPlay = false
)
}
}
}
videoplayer
@Composable
fun VideoPlayer(
vid: Video,
shouldPlay: Boolean
) {
val exoPlayer = rememberExoPlayerWithLifecycle(vid.url)
val playerView = rememberPlayerView(exoPlayer)
AndroidView(
factory = { playerView },
modifier = Modifier,
update = {
exoPlayer.playWhenReady = shouldPlay
}
)
DisposableEffect(key1 = true) {
onDispose {
exoPlayer.release()
}
}
}
rememberexoplayerwithlifecycle
@Composable
fun rememberExoPlayerWithLifecycle(
url: String
): ExoPlayer {
val context = LocalContext.current
val exoPlayer = remember(url) {
ExoPlayer.Builder(context).build().apply {
videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
repeatMode = Player.REPEAT_MODE_ONE
setHandleAudioBecomingNoisy(true)
val defaultDataSource = DefaultHttpDataSource.Factory()
val source = ProgressiveMediaSource.Factory(defaultDataSource)
.createMediaSource(MediaItem.fromUri(url))
setMediaSource(source)
prepare()
}
}
var appInBackground by remember {
mutableStateOf(false)
}
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(key1 = lifecycleOwner, appInBackground) {
val lifecycleObserver = getExoPlayerLifecycleObserver(exoPlayer, appInBackground) {
appInBackground = it
}
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
}
}
return exoPlayer
}
记住playplayerview
@Composable
fun rememberPlayerView(exoPlayer: ExoPlayer): PlayerView {
val context = LocalContext.current
val playerView = remember {
PlayerView(context).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
useController = false
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
player = exoPlayer
setShowBuffering(SHOW_BUFFERING_ALWAYS)
}
}
DisposableEffect(key1 = true) {
onDispose {
playerView.player = null
}
}
return playerView
}
build> build.gradle.gradle(project)
buildscript {
ext {
compose_version = '1.3.0-beta01'
}
}
plugins {
...
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
...
build。 gradle(模块)
...
dependencies {
...
//Pager
implementation "com.google.accompanist:accompanist-pager:0.26.2-beta"
//Media 3
def mediaVersion = "1.0.0-beta02"
implementation "androidx.media3:media3-exoplayer:$mediaVersion"
implementation "androidx.media3:media3-ui:$mediaVersion"
...
}
重叠项目
I have got two problems, scrolling through LazyColumn
or VerticalPager
with AndroidView
filling the whole screen as a child item lags the screen and the scrolling behavior for a couple of milliseconds as well as overlapping items. In my code the AndroidView
creates PlayerView
, I also tried to replace PlayerView
with a TextView
to check maybe the problem is with PlayerView
itself. I can't seem to find the root of the problem exactly, maybe with the AndroidView
or the implementation of the VerticalPager
itself, or maybe because it fills the whole screen?
ViewScreen
@OptIn(ExperimentalPagerApi::class)
@Composable
fun VideoScreen() {
val pagerState = rememberPagerState()
Box {
VerticalPager(
count = videos.size,
state = pagerState,
horizontalAlignment = Alignment.CenterHorizontally,
itemSpacing = 10.dp
) { index ->
VideoPlayer(
vid = videos[index],
shouldPlay = false
)
}
}
}
VideoPlayer
@Composable
fun VideoPlayer(
vid: Video,
shouldPlay: Boolean
) {
val exoPlayer = rememberExoPlayerWithLifecycle(vid.url)
val playerView = rememberPlayerView(exoPlayer)
AndroidView(
factory = { playerView },
modifier = Modifier,
update = {
exoPlayer.playWhenReady = shouldPlay
}
)
DisposableEffect(key1 = true) {
onDispose {
exoPlayer.release()
}
}
}
rememberExoPlayerWithLifecycle
@Composable
fun rememberExoPlayerWithLifecycle(
url: String
): ExoPlayer {
val context = LocalContext.current
val exoPlayer = remember(url) {
ExoPlayer.Builder(context).build().apply {
videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
repeatMode = Player.REPEAT_MODE_ONE
setHandleAudioBecomingNoisy(true)
val defaultDataSource = DefaultHttpDataSource.Factory()
val source = ProgressiveMediaSource.Factory(defaultDataSource)
.createMediaSource(MediaItem.fromUri(url))
setMediaSource(source)
prepare()
}
}
var appInBackground by remember {
mutableStateOf(false)
}
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(key1 = lifecycleOwner, appInBackground) {
val lifecycleObserver = getExoPlayerLifecycleObserver(exoPlayer, appInBackground) {
appInBackground = it
}
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
}
}
return exoPlayer
}
rememberPlayerView
@Composable
fun rememberPlayerView(exoPlayer: ExoPlayer): PlayerView {
val context = LocalContext.current
val playerView = remember {
PlayerView(context).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
useController = false
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
player = exoPlayer
setShowBuffering(SHOW_BUFFERING_ALWAYS)
}
}
DisposableEffect(key1 = true) {
onDispose {
playerView.player = null
}
}
return playerView
}
build.gradle (Project)
buildscript {
ext {
compose_version = '1.3.0-beta01'
}
}
plugins {
...
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
...
build.gradle (Module)
...
dependencies {
...
//Pager
implementation "com.google.accompanist:accompanist-pager:0.26.2-beta"
//Media 3
def mediaVersion = "1.0.0-beta02"
implementation "androidx.media3:media3-exoplayer:$mediaVersion"
implementation "androidx.media3:media3-ui:$mediaVersion"
...
}
Overlapping Items
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用expactratioframelayout.resize_mode_fit
Use AspectRatioFrameLayout.RESIZE_MODE_FIT
我遇到了同样的问题,并将垂直码器更新为0.25.1外部词汇到2.18.1,并使用了StyledPlayerview而不是Playerview,并且似乎在起作用。
I was having the same issue and update verticalpager to 0.25.1 exoplater to 2.18.1 and used a StyledPlayerView instead of PlayerView and it seems to be working.
而不是将
其替换为
instead of using
replace it with