Cicero
10/11/2021, 3:49 PMCicero
10/11/2021, 4:00 PMexerciseName: String?,
exerciseNameHasError: Boolean,
durationTimeState: State<String?>,
StepDescriptionItems: List<StepDescriptionItem>?,
bitmapState: State<Bitmap?>,
onMediaDeleteButtonClick: () -> Unit,
onOpenGalleryClick: () -> Unit,
onTakePhotoClicked: () -> Unit,
onCaptureVideoClick: () -> Unit,
onSaveButtonClick: () -> Unit,
onExerciseNameChange: (String) -> Unit,
onStepDescriptionValueChange: (index: Int, text: String) -> Unit,
onStepDescriptionFocusChange: (index: Int, focusState: FocusState) -> Unit,
onIncreaseDurationButtonClick: () -> Unit,
onDecreaseDurationButtonClick: () -> Unit,
onAddNewStepDescriptionClick: () -> Unit
with this implementation
CreateOrEditExerciseUI(
exerciseName = exerciseName,
exerciseNameHasError=exerciseNameHasError,
durationTimeState = timeFormatted,
bitmapState = previewBitmapState,
onMediaDeleteButtonClick = { viewModel.deleteVideoFile() },
onOpenGalleryClick = {
viewModel.getVideoUri()
?.let { openGalleryLauncher.launch(arrayOf("video/*", "image/*")) }
},
onTakePhotoClicked = { viewModel.getPictureUri()?.let { takePictureLauncher.launch(it) } },
onCaptureVideoClick = {
viewModel.getVideoUri()?.let { captureVideoLauncher.launch(it) }
},
onExerciseNameChange = viewModel.exerciseNameChange,
onSaveButtonClick =viewModel.validateAndSaveExercise,
StepDescriptionItems = stepDescriptions,
onStepDescriptionValueChange = { index, text ->
viewModel.modifyStepDescription(index, text, false)
},
onStepDescriptionFocusChange = { index, focusState ->
stepDescriptions?.let {
if (focusState.isFocused) {
val stepDescription = it[index]
viewModel.modifyStepDescription(index, stepDescription.string, false)
} else {
if (it[index].string.isEmpty() && it[index].needFocus == false) {
viewModel.removeStepDescriptionAt(index)
}
}
}
},
onIncreaseDurationButtonClick = viewModel.increaseDuration,
onDecreaseDurationButtonClick = viewModel.decreaseDuration,
onAddNewStepDescriptionClick = viewModel.addEmptyStepDescription
)
For my eye this reads clearly what it does. It's just passing the parameters that the UI require.
What could be done that I don't feel necessary is breaking it down into smaller widgets but in the end this UI do require all this parameters.
I know that there are some obvious improvements here to the way we pass in this parameters but besides this. Is there an architecture better than the classic:
@Composable
fun TestView(
action: MainActions,
viewModel: OnboardViewModel = getViewModel()
) {
TestUI(onClick = viewModel.clickMethod())
}
@Composable
fun TestUI(onClick: () -> Unit) {}
Damian Zawadzki
10/11/2021, 4:03 PMCicero
10/11/2021, 4:03 PM@Composable
fun FitnessItemDetailUI(
fitnessDetailItem: FitnessItemDetail?,
onClickBack: () -> Unit = {},
onAddFavorite: (FitnessItemDetail?) -> Unit = {},
exoPlayer: SimpleExoPlayer?,
isPlaying: Boolean,
onPlayPause: () -> Unit,
currentTime: Float = 50f,
totalTime: Float = 100f
) {
FitnessItemDetailScaffold(
fitnessDetailItem = fitnessDetailItem,
onClickBack = onClickBack,
onAddFavorite = onAddFavorite,
) {
AppLazyColumn {
item {
Column(
modifier = Modifier
.fillMaxSize()
.padding(gu())
) {
VideoPlayer(exoPlayer = exoPlayer)
PlayerSliderWithSoundController(currentTime, totalTime)
ExerciseTimeController()
PlayerControllerButtons(
isPlaying = isPlaying,
onPlayPauseClick = onPlayPause,
onFinishTrainingClick = {}
)
TrainingExercises(
currentTime = currentTime,
exercises = fitnessDetailItem.exercises
)
Instructions()
}
}
}
}
}
So the insides are not much of a problemDamian Zawadzki
10/11/2021, 4:06 PMCicero
10/11/2021, 4:07 PM@Composable
fun TestView(
action: MainActions,
viewModel: OnboardViewModel = getViewModel()
) {
TestUI(onClick = viewModel.clickMethod())
}
@Composable
fun TestUI(onClick: () -> Unit) {}
Cicero
10/11/2021, 4:08 PMCicero
10/11/2021, 4:10 PM@Composable
fun HeaderView(
action: MainActions,
viewModel: HeaderViewModel = getViewModel()
) {
HeaderUI(onClick = viewModel.clickMethod())
}
@Composable
fun HeaderUI(onClick: () -> Unit) {}
@Composable
fun BodyView(
action: MainActions,
viewModel: BodyViewModel = getViewModel()
) {
BodyUI(onClick = viewModel.clickMethod())
}
@Composable
fun BodyUI(onClick: () -> Unit) {}
Cicero
10/11/2021, 4:11 PMCicero
10/11/2021, 4:13 PMCsaba Szugyiczki
10/11/2021, 4:14 PMDamian Zawadzki
10/11/2021, 4:14 PMCsaba Szugyiczki
10/11/2021, 4:16 PMCicero
10/11/2021, 4:16 PM@Composable
fun HeaderView(
action: MainActions,
viewModel: HeaderViewModel = getViewModel()
) {
HeaderUI(onClick = viewModel.clickMethod())
}
@Composable
fun HeaderUI(onClick: () -> Unit) {}
Cicero
10/11/2021, 4:17 PMCicero
10/11/2021, 4:17 PMCicero
10/11/2021, 4:18 PMDamian Zawadzki
10/11/2021, 4:22 PMCsaba Kozák
10/11/2021, 5:43 PMadjpd
10/11/2021, 7:37 PMCicero
10/12/2021, 7:29 AMCicero
10/12/2021, 7:38 AMraenardev
10/12/2021, 8:56 AMonMediaDeleteButtonClick: () -> Unit,
onOpenGalleryClick: () -> Unit,
onTakePhotoClicked: () -> Unit,
onCaptureVideoClick: () -> Unit,
onSaveButtonClick: () -> Unit,
onExerciseNameChange: (String) -> Unit,
onStepDescriptionValueChange: (index: Int, text: String) -> Unit,
onStepDescriptionFocusChange: (index: Int, focusState: FocusState) -> Unit,
onIncreaseDurationButtonClick: () -> Unit,
onDecreaseDurationButtonClick: () -> Unit,
onAddNewStepDescriptionClick: () -> Unit
What if you represent those as Commands/Intents/Actions/Events instead?
sealed class Action {
object OpenGallery: Action()
object TakePhoto: Action()
}
So now you have something that looks like this:
exerciseName: String?,
exerciseNameHasError: Boolean,
durationTimeState: State<String?>,
StepDescriptionItems: List<StepDescriptionItem>?,
bitmapState: State<Bitmap?>,
onAction: (Action) -> Unit,
If you also wrap other stuff as your UI state, then it is even better:
state: State
onAction: (Action) -> Unit,
raenardev
10/12/2021, 9:17 AMadjpd
10/12/2021, 11:42 AMLilly
04/23/2022, 10:00 PMonStepDescriptionValueChange: (index: Int, text: String) -> Unit,
onStepDescriptionFocusChange: (index: Int, focusState: FocusState) -> Unit,
sealed class Action {
object OpenGallery: Action()
object TakePhoto: Action()
data class ChangeStepDescription(val index: Int, val text: String) : Action()
}
raenardev
04/25/2022, 3:15 PMLilly
04/25/2022, 5:38 PM