I want to make a feed with photos (glide) and videos (ExoPlayer media3), each post will have up to 20 attachments, which should be switched only by click (I want to use lazy row for optimization, because the task is such that the photo when switching quickly ,should be like a slide show)"
@Composable
fun HomeScreen(
navController: NavController,
navControllerMain: NavController
) {
val screenHeight = LocalConfiguration.current.screenHeightDp.dp
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val feedViewModel = FeedViewModel()
val listOfSenses by feedViewModel.listOfSenses.observeAsState(emptyList())
val currentSense by feedViewModel.currentSense.observeAsState(null)
val currentAttachmentIndex by feedViewModel.currentAttachmentIndex.observeAsState()
val listState = rememberLazyListState()
val rowState = rememberLazyListState()
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
itemsIndexed(listOfSenses) { index, sense ->
LazyRow(
modifier = Modifier.fillMaxWidth(),
state = rowState
) {
itemsIndexed(sense.Attachments) { indexAttachment, attachment ->
Box(
modifier = Modifier
.background(Color.Blue)
.fillMaxWidth()
.fillMaxHeight()
) {
PostCard(
attachment = attachment,
screenHeight = screenHeight,
screenWidth = screenWidth,
viewModel = feedViewModel,
sense = sense
)
}
}
}
}
}
}
}
ExoPlayer intercepts clicks, it is not possible to place them on composable elements, the toast only works here:
@Composable
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
fun VideoPlayer(
screenHeight: Dp,
screenWidth: Dp,
attachment: MediaAttachment,
viewModel: FeedViewModel
) {
val uri = Uri.parse("https://senses.team/${attachment.Video}")
val context = LocalContext.current
val exoPlayer = remember {
ExoPlayer.Builder(context)
.build()
.apply {
val defaultDataSourceFactory = DefaultDataSource.Factory(context)
val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(
context,
defaultDataSourceFactory
)
val source = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(uri))
setMediaSource(source)
prepare()
}
}
exoPlayer.playWhenReady = true
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
DisposableEffect(
AndroidView(
modifier = Modifier
.height(screenHeight)
.width(screenWidth)
.background(Color.Black),
factory = {
PlayerView(context).apply {
hideController()
useController = false
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
player = exoPlayer
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
setOnClickListener {
viewModel.onScreenTap()
Toast.makeText(context, viewModel.currentAttachmentIndex.value.toString(), Toast.LENGTH_SHORT).show()
}
}
})
) {
onDispose { exoPlayer.release() }
}
}
I want to use ViewModel to connect the player with the view feed:
class FeedViewModel : ViewModel() {
private val _listOfSenses = MutableLiveData<List<Sense>>(ListOfSenses)
val listOfSenses: LiveData<List<Sense>> = _listOfSenses
private val _currentSense = MutableLiveData<Sense>()
val currentSense: LiveData<Sense> = _currentSense
private val _currentAttachmentIndex = MutableLiveData(0)
val currentAttachmentIndex: LiveData<Int> = _currentAttachmentIndex
fun setCurrentSense(sense: Sense) {
_currentSense.value = sense
}
fun incAttachmentIndex() {
val currentSense = _currentSense.value
val currentAttachmentIndex = _currentAttachmentIndex.value
currentSense?.let { sense ->
val attachmentsSize = sense.Attachments?.size ?: 0
if (attachmentsSize > 0) {
val updatedAttachmentIndex = currentAttachmentIndex?.inc()?.rem(attachmentsSize)
_currentAttachmentIndex.value = updatedAttachmentIndex
}
}
}
fun onPlayVideoClick() {
}
fun onScreenTap() {
incAttachmentIndex()
}
}
I tried to attach a click handler to different elements of the view, but I couldn’t figure out how to scroll the row to the desired element when changing the data in the view model, I couldn’t remove the possibility of regular scrolling from the row the only thing I could achieve was that toast comes out when you click on the element I tried to change the row state using scrollToItem() in a coroutine that monitors the state of the currentAttachmentIndex variable