2

I have composable function in there’s some code is duplicate in if - else condition. Both if - else have same type of UI but different component. Inside if - else UI logic is similar to this answer. I want same UI logic in here.

Xyz

@Composable
fun Xyz(
    isTrue:Boolean,
    verticalArrangement: Arrangement.Vertical
) {
    AnimatedVisibility(true) {
        Column(
            modifier = Modifier
                .padding(10.dp)
                .fillMaxHeight()
                .verticalScroll(rememberScrollState()),
            verticalArrangement = verticalArrangement
        ) {
            if (isTrue) {
                Column(
                    modifier = Modifier
                        .verticalScroll(rememberScrollState())
                        .weight(1f),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    Image() // Duplicate code
                    Text() // Duplicate code
                    Image()
                    // more item in here
                }
                Column {
                    Button { action }
                    Button { action }
                }
            } else {
                Column(
                    modifier = Modifier
                        .verticalScroll(rememberScrollState())
                        .weight(1f),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    Image() // Duplicate code
                    Text() // Duplicate code
                    Image()
                    // more item in here
                }
                Column {
                    Button { action }
                }
            }
        }
    }
}

I am adding @Preview code for some understanding

@Preview
@Composable
fun XyzPreviewTop(){
    Theme {
        Xyz(false, Arrangement.Top)
    }
}

@Preview
@Composable
fun XyzPreviewSpaceBetween(){
    Theme {
        Xyz(false, Arrangement.SpaceBetween)
    }
}

@Preview
@Composable
fun XyzPreviewOneSpaceTop(){
    Theme {
        Xyz(true, Arrangement.Top)
    }
}

@Preview
@Composable
fun XyzPreviewOneSpaceBetween(){
    Theme {
        Xyz(true, Arrangement.SpaceBetween)
    }
}
  1. Inside if - else condition I had mention Duplicate code which means that code is using in both condition.

  2. How can we optimise if condition of both Column with else condition of both Column.

If you have question please ask me. Many Thanks

Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127
  • What is the purpose of `isTrue` exactly? Regardless, you should be able to move the if-statement to _inside_ where the composables would differ (i.e. the composable with one/two `Button`s respectively) – Edric Dec 06 '22 at 09:32
  • You can have a single `Column` moving the `if-else` inside, using ax external composable for the duplicate `Image`s – Gabriele Mariotti Dec 06 '22 at 09:32
  • @Edric `IsTrue` is kind of Bluetooth state i.e. **ON** and **OFF** on that bases I am showing UI. – Kotlin Learner Dec 06 '22 at 09:36
  • @GabrieleMariotti Can you please give me example for this? – Kotlin Learner Dec 06 '22 at 09:37

1 Answers1

3

You can use slot-based layouts of Jetpack Compose which increases reusability a lot.

Slot is basically creating content: @Composable () -> Unit like params like Scaffold, TopAppBar and other Composables have.

@Composable
fun Xyz(
    isTrue:Boolean,
    content: @Composable ()-> Unit,
    verticalArrangement: Arrangement.Vertical
) {
    AnimatedVisibility(true) {
        Column(
            modifier = Modifier
                .padding(10.dp)
                .fillMaxHeight()
                .verticalScroll(rememberScrollState()),
            verticalArrangement = verticalArrangement
        ) {
            if (isTrue) {
                Column(
                    modifier = Modifier
                        .verticalScroll(rememberScrollState())
                        .weight(1f),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    content()
                }
                Column {
                    Button {  }
                    Button { action }
                }
            } else {
                Column(
                    modifier = Modifier
                        .verticalScroll(rememberScrollState())
                        .weight(1f),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    content()
                }
                Column {
                    Button { action }
                }
            }
        }
    }
}

And you also create a ColumnScope receiver for content: @Composable ColumnScope.()-> Unit which will let you call scope specific modifiers like Modifier.weight inside your content

Thracian
  • 43,021
  • 16
  • 133
  • 222