58

I am using Jetpack Compose to create a simple flash card. The idea is that you click the flash card and it will give you the answer. However, I am stuck on a basic problem.

Unfortunately... I could not even find the official documentation, so my learning style has been trusting the autocorrect system...

Anyway, I believe the issue is either with Box() or Text(). I have added a Align.CenterEnd for the Gravity of the box. However, this seems to be the only way for centering in terms for the box. On the other hand, Text() does not give any methods to do so (It has gravity but it doesnt seem to be changing anything)

A hand in the right direction would be amazing.

On a side note, I know this would be giving free answers. But how would I change the text of $question inside the on click. As I thought Composables refresh?... thus, should regenerate on the screen? maybe not?

Thanks!

 val typography = MaterialTheme.typography

        val context = ContextAmbient.current
        var question = "How many Bananas should go in my Smoothie?"


        Column(modifier = Modifier.padding(30.dp).then(Modifier.fillMaxWidth())
                .then(Modifier.wrapContentSize(Alignment.Center))
                .clickable(onClick = { Toast.makeText(context, "3 Bananas are needed!", Toast.LENGTH_LONG).show()} ) /*question = "3 Bananas required"*/
                .clip(shape = RoundedCornerShape(16.dp))) {
            Box(modifier = Modifier.preferredSize(350.dp)
                    .gravity(align = Alignment.CenterHorizontally)
                    .border(width = 4.dp, color = Gray, shape = RoundedCornerShape(16.dp)),
            shape = RoundedCornerShape(2.dp),
            backgroundColor = DarkGray,
            gravity = Alignment.CenterEnd) {
                Text("$question",
                style = typography.h4,
                )
            }
        }

Picture of Current Content

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
PandaPlaysAll
  • 927
  • 2
  • 9
  • 15

5 Answers5

99

To define how to align the text horizontally you can apply textAlign = TextAlign.Center in the Text:

Column(modifier = Modifier
            .padding(30.dp)
            .fillMaxWidth()
            .wrapContentSize(Alignment.Center)
            .clickable(onClick = { } ) /*question = "3 Bananas required"*/
            .clip(shape = RoundedCornerShape(16.dp)),
) {
    Box(modifier = Modifier
            .preferredSize(350.dp)
            .border(width = 4.dp, color = Gray, shape = RoundedCornerShape(16.dp)),
             alignment = Alignment.Center
    ) {
        Text(
           text = "Question 1 : How many cars are in the garage?",
           modifier = Modifier.padding(16.dp),
           textAlign = TextAlign.Center,
           style = typography.h4,
        )
      //... 
   }
}
  

enter image description here

About the text.

You can use something like:

var text by remember { mutableStateOf(("How many cars are in the garage?")) }

In your clickable item:

.clickable(onClick = { text= "After clicking"} )

in your Text:

  Text(text, 
        textAlign = TextAlign.Center,
        ...)

It is just a simple. Instead of a static String you can use a dynamic structure to store and update the value.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • Thanks, the TextAlign was helpful. Is there official documentation for compose for each class? Ive been pretty confused on learning it. – PandaPlaysAll Sep 03 '20 at 20:31
  • @PandaPlaysAll Here you can find all [doc](https://developer.android.com/reference/kotlin/androidx/ui/classes). I've updated the answer with the link to `TextAlign` – Gabriele Mariotti Sep 03 '20 at 20:42
  • 7
    How can you align text to bottom or top? There is no option in TextAlignment for that? – Thracian Jan 01 '21 at 11:16
57

You can use textAlign to align your text horizontal and wrapContentHeight to align your text vertical within Text composable

Example centering text (both horizontal and vertical) within Text

Text(
    text = "How many cars are in the garage",
    textAlign = TextAlign.Center, // make text center horizontal
    modifier = Modifier
        .width(150.dp)
        .height(150.dp)
        .background(Color.Cyan)
        .wrapContentHeight() // make text center vertical
)

Example align bottom with center horizontal within Text

Text(
    text = "How many cars are in the garage",
    textAlign = TextAlign.Center, // make text center horizontal
    modifier = Modifier
        .width(150.dp)
        .height(150.dp)
        .background(Color.Cyan)
        .wrapContentHeight(Alignment.Bottom) // align bottom
)

Example align bottom with center horizontal within a Box

Box(modifier = Modifier
    .width(150.dp)
    .height(150.dp)
    .background(Color.Cyan),
    contentAlignment = Alignment.BottomCenter
) {
    Text(
        text = "How many cars are in the garage",
        textAlign = TextAlign.Center
    )
}
Linh
  • 57,942
  • 23
  • 262
  • 279
  • 1
    doesn't when you have for example `minLines = 3` and currently `Text` contains only one line, it's still centered only horizontally but not vertically – user924 Mar 14 '23 at 21:51
  • @user924 This is true, `minLines` does cause the height to increase but the text stays at the top. This is the work around I use: https://github.com/imashnake0/Animite/blob/8a7d0d45a0a51741edf204fb0d5a1ad14716b6dd/app/src/main/java/com/imashnake/animite/features/ui/MediaSmall.kt#L107-L135 – imashnake_ May 25 '23 at 09:03
  • 1
    You can use `size(150.dp)` instead of `width` and `height`. – salmanseifian Jul 19 '23 at 13:54
4
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxHeight()) 
{
    Text(text = "Text"),
    textAlign = TextAlign.Center,
}
lemon
  • 14,875
  • 6
  • 18
  • 38
Abhinav Chauhan
  • 1,304
  • 1
  • 7
  • 24
2

The following worked for me:

Text(modifier = Modifier.fillMaxWidth(), text = "TEST", textAlign = TextAlign.Center)
J. Doe
  • 12,159
  • 9
  • 60
  • 114
0
// You can apply textAlign = TextAlign.Center

 Text( text = "My name is $name",
        color = MaterialTheme.colors.primary,
        fontSize = 32.sp,
        fontFamily = FontFamily.Cursive,
        textAlign = TextAlign.Center,
        modifier = Modifier.clickable {
            Toast.makeText(context, "Hello Friends"Toast.LENGTH_LONG).show()
        })