Что я пробовал:
- Проверка того, что состояние действительно обновляется должным образом (так и есть)
- Проверка компонуемой перекомпозиции (она происходит, и даже когда состояние обновляется, пользовательский интерфейс не всегда меняется, но перекомпонуется)
- Проверка фактической выбранной песни не вызывает этой проблемы ( одна и та же песня/данные иногда работают, но в большинстве случаев не работают, поэтому это не связано)
- Проверка того, работает ли один и тот же компонуемый объект на полностью компонуемом экране (так и есть)
- Обновление спецификации составления до последней версии (использовалась версия 2024.05.00, а теперь 2024.08.00)
- Обновление Android Studio
- Воздействие со стратегией композиции представлений ComposeView
- Использование ObserveAsState() вместо ObserveAsStateWithLifecycle()
Часть XML-макета, содержащая ComposeView
Как разместить составной контент в ComposeView
ui.miniPlayerView.setContent {
AppTheme {
MiniAudioPlayer()
}
}
Компонуемый
private const val MINIMUM_DRAG_AMOUNT = -100f
@Composable
fun MiniAudioPlayer(
modifier: Modifier = Modifier,
playerHandler: PlayerHandler = koinInject()
) {
val context = LocalContext.current
val state by playerHandler.miniPlayerState.collectAsStateWithLifecycle()
val progress by remember { derivedStateOf { state.progress } }
val showPlayer by remember { derivedStateOf { state.showPlayer } }
val isPlaying by remember { derivedStateOf { state.isPlaying } }
val title by remember { derivedStateOf { state.title } }
val thumbnailUrl by remember { derivedStateOf { state.thumbnailUrl } }
var totalDragAmount by remember { mutableFloatStateOf(0f) }
val interactionSource = remember { MutableInteractionSource() }
if (showPlayer) {
Row(
modifier = modifier
.clickable(interactionSource = interactionSource, indication = null) { context.openAudioPlayer() }
.pointerInput(Unit) {
detectVerticalDragGestures(
onDragStart = { totalDragAmount = 0f },
) { _, dragAmount ->
totalDragAmount += dragAmount
if (totalDragAmount < MINIMUM_DRAG_AMOUNT) context.openAudioPlayer()
}
}
.background(color = LocalCustomColors.current.background)
.background(color = colorResource(R.color.miniplayer_background))
.padding(16.dp),
) {
MMImage(
url = thumbnailUrl,
size = DpSize(54.dp, 54.dp),
modifier = Modifier
.size(54.dp)
.clip(RoundedCornerShape(8.dp))
)
Spacer(modifier = Modifier.width(12.dp))
Column(
modifier = Modifier
.weight(1f)
) {
Spacer(modifier = Modifier.height(8.dp))
Header5Text(
text = title,
maxLines = 1
)
Spacer(modifier = Modifier.height(10.dp))
MMProgressBar(progress = { progress })
}
Spacer(modifier = Modifier.width(18.dp))
MMIcon(
drawableId = if (isPlaying) R.drawable.ic_miniplayer_pause_button else R.drawable.ic_miniplayer_play_button,
size = 34.dp,
modifier = Modifier
.clickable(interactionSource = interactionSource, indication = null) {
playerHandler.togglePlayState()
}
.align(Alignment.CenterVertically)
)
}
}
}
Как обновить значения в ViewModel (класс PlayerHandler)
private val _miniPlayerState = MutableStateFlow(MiniPlayerUiState())
val miniPlayerState = _miniPlayerState.asStateFlow()
_miniPlayerState.update { it.copy(progress = progress / 100f) }
Государство
data class MiniPlayerUiState(
val showPlayer: Boolean = false,
val isPlaying: Boolean = false,
val progress: Float = 0f,
val title: String = "",
val thumbnailUrl: String? = null
)
Подробнее здесь: https://stackoverflow.com/questions/789 ... recomposes