I am trying out the Jetpack compose, but while creating the UI I need to declare in a composable function something as shown below.
@Composable
fun ExampleScreen()
{
val column = MyColumn()
val text1 = MyText()
val button1 = MyButton()
column.CreateColumn(pVerticalArrangement = Arrangement.Center, pHorizontalAlignment = Alignment.CenterHorizontally, pBackgroundColor = Color.LightGray, pPadding = 20)
{
text1.CreateText(pText = "First Text", pFontWeight = FontWeight.Bold, pFontSize = 18, pTextColor = Color.Blue, pModifier = Modifier.padding(bottom = 8.dp))
button1.CreateButton(pText = "Button1", pOnClick = { HandleClick(1) }, pTextColor = Color.Black, pWidth = 250, pHeight = 50, pModifier = Modifier.padding(bottom = 8.dp))
}
}
This is how I have made the widgets by creating a wrapper to make it reusable for now.
class MyText {
// Reusable Text Composable
@Composable
fun CreateText(pText: String, pModifier: Modifier = Modifier, pFontSize: Int = 16, pFontWeight: FontWeight = FontWeight.Normal, pTextColor: Color = Color.Black)
{
Text(text = pText, fontSize = pFontSize.sp, fontWeight = pFontWeight, color = pTextColor, modifier = pModifier)
}
}
As you can see the Example Screen composable function it is declared already with some widgets. Is it not possible to declare those widgets during runtime?
Edited: Consider now we rendered the screen, with the above code and now any user event(Like Button Click) it processed some information and now I want to show different UI with different widgets, so how should I do in these scenario? Should I call different composable function?
Edited2: Consider I am creating a text.kt for Text, a button.kt for Button and a container (for say Column.kt). We want to create the UI with 1 container and 5 widgets (Button/Text) and the number of widgets is not pre-known and comes during runtime after some computations. So, how to do this?
I am trying out the Jetpack compose, but while creating the UI I need to declare in a composable function something as shown below.
@Composable
fun ExampleScreen()
{
val column = MyColumn()
val text1 = MyText()
val button1 = MyButton()
column.CreateColumn(pVerticalArrangement = Arrangement.Center, pHorizontalAlignment = Alignment.CenterHorizontally, pBackgroundColor = Color.LightGray, pPadding = 20)
{
text1.CreateText(pText = "First Text", pFontWeight = FontWeight.Bold, pFontSize = 18, pTextColor = Color.Blue, pModifier = Modifier.padding(bottom = 8.dp))
button1.CreateButton(pText = "Button1", pOnClick = { HandleClick(1) }, pTextColor = Color.Black, pWidth = 250, pHeight = 50, pModifier = Modifier.padding(bottom = 8.dp))
}
}
This is how I have made the widgets by creating a wrapper to make it reusable for now.
class MyText {
// Reusable Text Composable
@Composable
fun CreateText(pText: String, pModifier: Modifier = Modifier, pFontSize: Int = 16, pFontWeight: FontWeight = FontWeight.Normal, pTextColor: Color = Color.Black)
{
Text(text = pText, fontSize = pFontSize.sp, fontWeight = pFontWeight, color = pTextColor, modifier = pModifier)
}
}
As you can see the Example Screen composable function it is declared already with some widgets. Is it not possible to declare those widgets during runtime?
Edited: Consider now we rendered the screen, with the above code and now any user event(Like Button Click) it processed some information and now I want to show different UI with different widgets, so how should I do in these scenario? Should I call different composable function?
Edited2: Consider I am creating a text.kt for Text, a button.kt for Button and a container (for say Column.kt). We want to create the UI with 1 container and 5 widgets (Button/Text) and the number of widgets is not pre-known and comes during runtime after some computations. So, how to do this?
Share Improve this question edited yesterday Rohan Pande asked yesterday Rohan PandeRohan Pande 2954 silver badges10 bronze badges 2- Everything you do in Jetpack Compose is 'during runtime'. None of what you've shown makes any sense at all, which leads me to believe perhaps we're suffering from an XY Problem where there's some other requirements at play that you did not mention here that is causing you to even consider this. Please consider editing your question with some more details on why you think you need to do this. – ianhanniballake Commented yesterday
- @ianhanniballake I have updated the question can you please go through this again? – Rohan Pande Commented yesterday
1 Answer
Reset to default 2This is how I have made the widgets by creating a wrapper to make it reusable for now.
First, placing Composable functions into a class
is not common. Usually, you put a Composable function into a Kotlin file directly as a top level function. Then, it is available to the whole package without an import, or usable everywhere with a respective import.
You can limit visibility using the private
keyword, then it is only accessible in the same file.
In your case, if you want the MyText
Composable to be isolated from the rest, you would do it as follows:
MyText.kt
// Reusable Text Composable
@Composable
fun MyText(pText: String, pModifier: Modifier = Modifier, pFontSize: Int = 16, pFontWeight: FontWeight = FontWeight.Normal, pTextColor: Color = Color.Black)
{
Text(text = pText, fontSize = pFontSize.sp, fontWeight = pFontWeight, color = pTextColor, modifier = pModifier)
}
Note that you can simply call predefined Composable functions directly, you don't need to wrap each of them in your own Composable, in case you were not aware of that:
MainActivity.kt
@Composable
fun ExampleScreen(HandleClick: (Int) -> Unit) {
// example variable
var clickCounter by remember { mutableIntStateOf(0) }
// you can also directly invoke the OOTB Column,
// it seems a little unnecessary to implement your own Column Composable here
Column(
modifier = Modifier
.padding(20dp)
.background(Color.LightGray),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
MyText(
pText = "First Text",
pFontWeight = FontWeight.Bold,
pFontSize = 18,
pTextColor = Color.Blue,
pModifier = Modifier.padding(bottom = 8.dp)
)
MyButton(
pText = "Button1",
pOnClick = { clickCounter++ },
pTextColor = Color.Black,
pWidth = 250,
pHeight = 50,
pModifier = Modifier.padding(bottom = 8.dp)
)
}
}
Is it not possible to declare those widgets during runtime?
I think what you wanted to ask is:
Is it not possible to dynamically show or hide widgets?"
You can add conditional logic to dynamically determine which Composable should be shown:
if (clickCounter > 3) {
MyText(
pText = "First Text",
pFontWeight = FontWeight.Bold,
pFontSize = 18,
pTextColor = Color.Blue,
pModifier = Modifier.padding(bottom = 8.dp)
)
}
// number of displayed Composables changes dynamically
repeat(clickCounter) { counter ->
MyText(
pText = "Text $counter",
pFontWeight = FontWeight.Bold,
pFontSize = 18,
pTextColor = Color.Blue,
pModifier = Modifier.padding(bottom = 8.dp)
)
}
Additionally, you can pass Composables as arguments, as in below example:
@Composable
fun LabelledContent(
modifier: Modifier = Modifier,
label: @Composable () -> Unit,
content: @Composable ColumnScope.() -> Unit
) {
Column {
label()
content()
}
}