添加短视频
This commit is contained in:
@@ -189,8 +189,11 @@ fun Navigation(){
|
||||
|
||||
@Composable
|
||||
fun Home(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight)),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
){
|
||||
@@ -201,8 +204,11 @@ fun Home(){
|
||||
|
||||
@Composable
|
||||
fun Street(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight)),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
@@ -212,9 +218,12 @@ fun Street(){
|
||||
|
||||
@Composable
|
||||
fun Add(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight))
|
||||
.background(Color.Black),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
@@ -225,8 +234,11 @@ fun Add(){
|
||||
|
||||
@Composable
|
||||
fun Video(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight)),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
){
|
||||
@@ -236,8 +248,11 @@ fun Video(){
|
||||
|
||||
@Composable
|
||||
fun Message(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight)),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
){
|
||||
@@ -247,8 +262,11 @@ fun Message(){
|
||||
|
||||
@Composable
|
||||
fun Profile(){
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = (56.dp + navigationBarHeight)),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
){
|
||||
|
||||
@@ -17,7 +17,7 @@ sealed class NavigationItem(val route:String, val icon: @Composable () -> ImageV
|
||||
data object Add : NavigationItem("Add",
|
||||
{ ImageVector.vectorResource(R.drawable.rider_pro_moment_add) })
|
||||
data object Message : NavigationItem("Message",
|
||||
{ ImageVector.vectorResource(R.drawable.rider_pro_message) })
|
||||
{ ImageVector.vectorResource(R.drawable.rider_pro_video) })
|
||||
data object Profile : NavigationItem("Profile",
|
||||
{ ImageVector.vectorResource(R.drawable.rider_pro_profile) })
|
||||
}
|
||||
@@ -8,9 +8,10 @@ import com.aiosman.riderpro.ShortViewCompose
|
||||
import com.aiosman.riderpro.ui.theme.RiderProTheme
|
||||
|
||||
val videoUrls = listOf(
|
||||
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4",
|
||||
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4"
|
||||
"https://api.aiosman.com/video/1.mp4",
|
||||
"https://api.aiosman.com/video/2.mp4",
|
||||
"https://api.aiosman.com/video/3.mp4",
|
||||
"https://api.aiosman.com/video/4.mp4"
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,23 +2,45 @@ package com.aiosman.riderpro
|
||||
|
||||
import android.app.Activity
|
||||
import android.net.Uri
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.MediaItem
|
||||
@@ -111,7 +133,7 @@ fun VideoPlayer(
|
||||
val scope= rememberCoroutineScope()
|
||||
|
||||
val exoPlayer = remember {
|
||||
SimpleExoPlayer.Builder(context)
|
||||
ExoPlayer.Builder(context)
|
||||
.build()
|
||||
.apply {
|
||||
val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(
|
||||
@@ -130,42 +152,123 @@ fun VideoPlayer(
|
||||
} else {
|
||||
exoPlayer.pause()
|
||||
}
|
||||
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
|
||||
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
|
||||
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
|
||||
DisposableEffect(
|
||||
Box(modifier = Modifier.fillMaxSize()){
|
||||
AndroidView(factory = {
|
||||
PlayerView(context).apply {
|
||||
hideController()
|
||||
useController = false
|
||||
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
|
||||
Box(modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.TopCenter) {
|
||||
var playerView by remember { mutableStateOf<PlayerView?>(null) } // Store reference to PlayerView
|
||||
|
||||
player = exoPlayer
|
||||
layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
// 创建一个 FrameLayout 作为容器
|
||||
FrameLayout(context).apply {
|
||||
// 设置背景颜色为黑色,用于显示黑边
|
||||
setBackgroundColor(Color.Black.toArgb())
|
||||
|
||||
// 创建 PlayerView 并添加到 FrameLayout 中
|
||||
val view = PlayerView(context).apply {
|
||||
hideController()
|
||||
useController = false
|
||||
player = exoPlayer
|
||||
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL // 或 RESIZE_MODE_ZOOM
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
Gravity.CENTER
|
||||
)
|
||||
}
|
||||
addView(view)
|
||||
}
|
||||
},modifier = Modifier.noRippleClickable {
|
||||
pauseIconVisibleState.value=true
|
||||
},
|
||||
modifier = Modifier.noRippleClickable {
|
||||
pauseIconVisibleState.value = true
|
||||
exoPlayer.pause()
|
||||
scope.launch {
|
||||
delay(500)
|
||||
delay(100)
|
||||
if (exoPlayer.isPlaying) {
|
||||
exoPlayer.pause()
|
||||
} else {
|
||||
pauseIconVisibleState.value=false
|
||||
pauseIconVisibleState.value = false
|
||||
exoPlayer.play()
|
||||
}
|
||||
}
|
||||
})
|
||||
if (pauseIconVisibleState.value)
|
||||
Icon(imageVector = Icons.Default.PlayArrow, contentDescription = null,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(80.dp))
|
||||
}
|
||||
)
|
||||
|
||||
if (pauseIconVisibleState.value) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.PlayArrow,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(80.dp)
|
||||
)
|
||||
}
|
||||
) {
|
||||
onDispose {
|
||||
exoPlayer.release()
|
||||
|
||||
// Release ExoPlayer when the videoUrl changes or the composable leaves composition
|
||||
DisposableEffect(videoUrl) {
|
||||
onDispose {
|
||||
exoPlayer.release()
|
||||
playerView?.player = null
|
||||
playerView = null // Release the reference to the PlayerView
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Box(modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.BottomEnd){
|
||||
Column (modifier = Modifier.padding(bottom = 72.dp, end = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally){
|
||||
UserAvatar()
|
||||
VideoBtn(icon = R.drawable.rider_pro_video_like, text = "975.9k")
|
||||
VideoBtn(icon = R.drawable.rider_pro_video_comment, text = "1896")
|
||||
VideoBtn(icon = R.drawable.rider_pro_video_favor, text = "234")
|
||||
VideoBtn(icon = R.drawable.rider_pro_video_share, text = "677k")
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.BottomStart){
|
||||
Column (modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)){
|
||||
Row (modifier = Modifier.padding(bottom = 8.dp).background(color = Color.Gray),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
){
|
||||
Image(modifier = Modifier.size(20.dp).padding(start = 4.dp, end = 6.dp), painter = painterResource(id = R.drawable.rider_pro_video_location), contentDescription = "")
|
||||
Text(modifier = Modifier.padding(end = 4.dp),text = "USA",fontSize = 12.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
|
||||
}
|
||||
Text(text = "@Kevinlinpr",fontSize = 16.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 4.dp), // 确保Text占用可用宽度
|
||||
text = "Pedro Acosta to join KTM in 2025 on a multi-year deal! \uD83D\uDFE0",
|
||||
fontSize = 16.sp,
|
||||
color = Color.White,
|
||||
style = TextStyle(fontWeight = FontWeight.Bold),
|
||||
overflow = TextOverflow.Ellipsis, // 超出范围时显示省略号
|
||||
maxLines = 2 // 最多显示两行
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UserAvatar(){
|
||||
Image(modifier = Modifier.padding(bottom = 16.dp).size(40.dp).border(width = 3.dp, color = Color.White, shape = RoundedCornerShape(40.dp)).clip(
|
||||
RoundedCornerShape(40.dp)
|
||||
), painter = painterResource(id = R.drawable.default_avatar), contentDescription = "")
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun VideoBtn(@DrawableRes icon: Int, text: String){
|
||||
Column (
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
){
|
||||
Image(modifier = Modifier.size(36.dp), painter = painterResource(id = icon), contentDescription = "")
|
||||
Text(text = text,fontSize = 11.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,4 +280,3 @@ fun VideoPlayer(
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user