loloof64
04/29/2021, 11:45 AMRestartable
Composable
. This component needs to be restarted when the user makes a restart request. In previous Android development, this could be achieved by calling on of Restartable
methods, if Restartable
was designed as a class. But, talking about Composition
, what should be a good pattern to achieve this. More on my attempt in thread.loloof64
04/29/2021, 11:48 AM@Composable
fun Restartable(
startId: Long = 1L
) {
var currentStartId by rememberSaveable{mutableStateOf(startId)}
fun restart() {
...
}
if (currentStartId != startId) {
restart()
currentStartId = startId
}
}
Is this a good pattern or can I do better ?
Is this in the spirit of Jetpack Compose ?Adam Powell
04/29/2021, 1:19 PMrestart
is a side effect that you're triggering. If the user requested an operation, perform that operation in response to the user input event handler directly. That operation changes app data, and app data changing may cause recomposition to update your UI. Don't use recomposition itself as an event handler.loloof64
04/29/2021, 3:39 PMloloof64
04/29/2021, 3:48 PM@Composable
fun Restartable(
restart: () -> Unit,
) {
}
Then I don't know how to "call" the restart
callback from the caller code.Adam Powell
04/29/2021, 5:12 PMloloof64
04/29/2021, 5:23 PMDynamicChessBoard
that I'm developping for my project.
DynamicChessBoard
is an interactive chess board composable, but with an initial position as string (in Forsyth-Edwards Notation).
So this chess board has a startPosition as parameter, as well as a mutableState<String>, stored with rememberSaveable
.
But by a click on an external button, a user may request to start a new game from the initial position. Let's call this the restart event
.
How can make a click on the RestartButton
make the DynamicChessBoard
restart the game ?
If I code inside DynamicChessBoard
a restartGame
function, I won't be able to access it from outside. So what should I do instead.
Sorry, I did not post the code for DynamicChessBoard
as it is very complex as now and very long.loloof64
04/29/2021, 5:24 PMAdam Powell
04/29/2021, 5:29 PMremember {}
/`rememberSaveable {}`d by the caller. A restartGame
function can exist on that class and the UI can call it.Adam Powell
04/29/2021, 5:31 PMmutableStateOf
and replace the old state with a fresh/initial one when the restart game button is clickedAdam Powell
04/29/2021, 5:32 PMloloof64
04/29/2021, 5:37 PMmutableStateOf
πloloof64
04/29/2021, 7:39 PMenum class NewGameRequestState {
REQUEST_PENDING,
NO_PENDING_REQUEST,
}
@Composable
fun DynamicChessBoard(
...
newGameRequest: NewGameRequestState = NewGameRequestState.NO_PENDING_REQUEST,
newGameRequestProcessedCallback : () -> Unit
...
) {
val aNewGameIsRequested = newGameRequest == NewGameRequestState.REQUEST_PENDING
if (aNewGameIsRequested) {
startNewGame()
newGameRequestProcessedCallback()
}
}
And calling the DynamicChessBoard
like this :
var requestNewGameState by remember{mutableStateOf(NewGameRequestState.NO_PENDING_REQUEST)}
fun requestANewGame() {
requestNewGameState = NewGameRequestState.REQUEST_PENDING
}
DynamicChessBoard(
newGameRequest = requestNewGameState,
newGameRequestProcessedCallback = {
// we clear the newGameRequestState
newGameRequestState = NewGameRequestState.NO_PENDING_REQUEST})
Adam Powell
04/29/2021, 7:55 PMloloof64
04/29/2021, 8:23 PMloloof64
04/30/2021, 10:54 AMAdam Powell
04/30/2021, 3:13 PMclass PositionHandler(startPosition: String) {
var currentPosition: String = "8/8/8/8/8/8/8/8 w - - 0 1"
private set
to
class PositionHandler(
private val startPosition: String = "8/8/8/8/8/8/8/8 w - - 0 1"
) {
var currentPosition: String by mutableStateOf(startPosition)
private set
and change
@Composable
fun DynamicChessBoard(
...
positionHandler: PositionHandler
...
) {
...
var position by remember{ mutableStateOf(positionHandler) }
to
@Composable
fun DynamicChessBoard(
...
position: PositionHandler = remember { PositionHandler() }
...
) {
...
loloof64
04/30/2021, 6:55 PMloloof64
04/30/2021, 7:02 PMDynamicChessBoard
for the host Composable
to update its hoisted state itself in reaction to some DynamicChessBoard
events ?
For example :
var gameInProgress by remember{mutableStateOf(false)}
DynamicChessBoard(
gameInProgress = gameInProgress
gameEndedCallback = {
if (it != GameStatus.GOING_ON) gameInProgress = false
}
)
@Composable
fun DynamicChessBoard(
gameInProgress: Boolean,
gameEndedCallback : (GameStatus) -> Unit,
) {
fun handleDragAndDrop() {
if (gameInProgress) {
// handle drag and drop
}
}
fun checkGameEndedStatus() {
val gameEndedStatus = /* */
if (gameEndedStatus != GameEndedStatus.GOING_ON) {
gameEndedCallBack(gameEndedStatus)
}
}
}
Adam Powell
04/30/2021, 9:36 PMloloof64
04/30/2021, 10:00 PM