fix content ratio using compose
This commit is contained in:
parent
356744814c
commit
4089de7272
|
@ -0,0 +1,41 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -24,6 +24,7 @@ import android.app.Application
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
|
@ -40,16 +41,25 @@ import net.newpipe.newplayer.NewPlayer
|
|||
|
||||
val VIDEOPLAYER_UI_STATE = "video_player_ui_state"
|
||||
|
||||
private const val TAG = "VideoPlayerViewModel"
|
||||
|
||||
@Parcelize
|
||||
data class VideoPlayerUIState(
|
||||
val playing: Boolean,
|
||||
var fullscreen: Boolean,
|
||||
var uiVissible: Boolean,
|
||||
var contentRatio: Float
|
||||
var contentRatio: Float,
|
||||
var minContentRatio: Float,
|
||||
var maxContentRatio: Float
|
||||
) : Parcelable {
|
||||
companion object {
|
||||
val DEFAULT = VideoPlayerUIState(
|
||||
playing = false, fullscreen = false, uiVissible = false, 0F
|
||||
playing = false,
|
||||
fullscreen = false,
|
||||
uiVissible = false,
|
||||
contentRatio = 0F,
|
||||
minContentRatio = 4F / 3F,
|
||||
maxContentRatio = 16F / 9F
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +69,8 @@ interface VideoPlayerViewModel {
|
|||
val player: Player?
|
||||
val uiState: StateFlow<VideoPlayerUIState>
|
||||
var listener: Listener?
|
||||
var minContentRatio: Float
|
||||
var maxContentRatio: Float
|
||||
|
||||
fun initUIState(instanceState: Bundle)
|
||||
fun play()
|
||||
|
@ -78,7 +90,6 @@ interface VideoPlayerViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class VideoPlayerViewModelImpl @Inject constructor(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
|
@ -102,8 +113,33 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
override val player: Player?
|
||||
get() = newPlayer?.player
|
||||
|
||||
override var minContentRatio: Float
|
||||
set(value) {
|
||||
if (value <= 0 || mutableUiState.value.maxContentRatio < value)
|
||||
Log.e(
|
||||
TAG,
|
||||
"Ignoring maxContentRatio: It must not be 0 or less and it may not be bigger then mmaxContentRatio. It was Set to: $value"
|
||||
)
|
||||
else
|
||||
mutableUiState.update { it.copy(minContentRatio = value) }
|
||||
}
|
||||
get() = mutableUiState.value.minContentRatio
|
||||
|
||||
override var maxContentRatio: Float
|
||||
get() = mutableUiState.value.maxContentRatio
|
||||
set(value) {
|
||||
if (value <= 0 || value < mutableUiState.value.minContentRatio)
|
||||
Log.e(
|
||||
TAG,
|
||||
"Ignoring maxContentRatio: It must not be 0 or less and it may not be smaller then minContentRatio. It was Set to: $value"
|
||||
)
|
||||
else
|
||||
mutableUiState.update { it.copy(maxContentRatio = value) }
|
||||
}
|
||||
|
||||
private fun installExoPlayer() {
|
||||
player?.let { player ->
|
||||
Log.i(TAG, "Install player")
|
||||
player.addListener(object : Player.Listener {
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
super.onIsPlayingChanged(isPlaying)
|
||||
|
@ -143,17 +179,17 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
println("gurken viewmodel cleared")
|
||||
Log.d(TAG, "viewmodel cleared")
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
override fun initUIState(instanceState: Bundle) {
|
||||
|
||||
val uiState =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
|
||||
instanceState.getParcelable(VIDEOPLAYER_UI_STATE, VideoPlayerUIState::class.java)
|
||||
else
|
||||
instanceState.getParcelable(VIDEOPLAYER_UI_STATE)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) instanceState.getParcelable(
|
||||
VIDEOPLAYER_UI_STATE, VideoPlayerUIState::class.java
|
||||
)
|
||||
else instanceState.getParcelable(VIDEOPLAYER_UI_STATE)
|
||||
|
||||
uiState?.let { uiState ->
|
||||
mutableUiState.update {
|
||||
|
@ -171,11 +207,11 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
}
|
||||
|
||||
override fun prevStream() {
|
||||
println("imeplement prev stream")
|
||||
Log.e(TAG, "imeplement prev stream")
|
||||
}
|
||||
|
||||
override fun nextStream() {
|
||||
println("implement next stream")
|
||||
Log.e(TAG, "implement next stream")
|
||||
}
|
||||
|
||||
override fun switchToEmbeddedView() {
|
||||
|
@ -196,7 +232,8 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
override val player: Player? = null
|
||||
override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
|
||||
override var listener: VideoPlayerViewModel.Listener? = null
|
||||
|
||||
override var minContentRatio = 4F / 3F
|
||||
override var maxContentRatio = 16F / 9F
|
||||
|
||||
override fun initUIState(instanceState: Bundle) {
|
||||
println("dummy impl")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.newpipe.newplayer.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Surface
|
||||
|
@ -16,9 +17,9 @@ import androidx.compose.ui.unit.dp
|
|||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||
|
||||
@Composable
|
||||
fun VideoPlayerLoadingPlaceholder() {
|
||||
fun VideoPlayerLoadingPlaceholder(aspectRatio:Float = 3F/1F) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth().height(200.dp),
|
||||
modifier = Modifier.fillMaxWidth().aspectRatio(aspectRatio),
|
||||
color = Color.Black
|
||||
) {
|
||||
Box {
|
||||
|
|
|
@ -25,7 +25,9 @@ import android.view.SurfaceView
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
|
@ -53,8 +55,10 @@ import net.newpipe.newplayer.utils.findActivity
|
|||
fun VideoPlayerUI(
|
||||
viewModel: VideoPlayerViewModel?,
|
||||
) {
|
||||
if (viewModel?.player == null) {
|
||||
if (viewModel == null) {
|
||||
VideoPlayerLoadingPlaceholder()
|
||||
} else if (viewModel.player == null) {
|
||||
VideoPlayerLoadingPlaceholder(viewModel.uiState.collectAsState().value.maxContentRatio)
|
||||
} else {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
|
||||
|
@ -106,8 +110,13 @@ fun VideoPlayerUI(
|
|||
}
|
||||
|
||||
// Set UI
|
||||
val aspectRatio =
|
||||
uiState.contentRatio.coerceIn(uiState.minContentRatio, uiState.maxContentRatio)
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(aspectRatio),
|
||||
color = Color.Black
|
||||
) {
|
||||
AndroidView(
|
||||
|
|
|
@ -51,6 +51,8 @@ class MainActivity : AppCompatActivity() {
|
|||
video_view.viewModel = videoPlayerViewModel
|
||||
videoPlayerViewModel.newPlayer = newPlayer
|
||||
|
||||
videoPlayerViewModel.maxContentRatio = 4F/3F
|
||||
|
||||
/*
|
||||
video_view.fullScreenToggleListener = object : VideoPlayerView.FullScreenToggleListener {
|
||||
override fun fullscreenToggle(turnOn: Boolean) {
|
||||
|
|
Loading…
Reference in New Issue