Change layout direction of a Composable - android

I want to set a direction of a specific composable to be RTL
#Composable
fun ViewToBeChanged() {
Row {
Image()
Column {
Text("Title")
Text("Subtitle")
}
}
}
Is it possible?
Jetpack compose Layout documentation mentions LocalLayoutDirection
Change the layout direction of a composable by changing the LocalLayoutDirection compositionLocal.
But I have no idea how to use it in a composable to take effect.

You can use the CompositionLocalProvider to provide a custom LocalLayoutDirection.
Something like:
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
Column(Modifier.fillMaxWidth()) {
Text("Title")
Text("Subtitle")
}
}

Since I did not have your image, I tweaked your composable to:
#Composable
fun ViewToBeChanged() {
Row {
Text("Foo", modifier = Modifier.padding(end = 8.dp))
Column {
Text("Title")
Text("Subtitle")
}
}
}
That gives us:
One way to switch to RTL is to use CompositionLocalProvider and LocalLayoutDirection:
#Composable
fun RtlView() {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Row {
Text("Foo", modifier = Modifier.padding(end = 8.dp))
Column {
Text("Title")
Text("Subtitle")
}
}
}
}
Here, we are saying that we are overriding the CompositionLocal for layout direction for the contents of the trailing lambda supplied to CompositionLocalProvider(). This gives us:
This changes the layout direction used by this branch of the composable tree, for the composables itself. English is still a LTR language, so the text is unaffected.

As a generalisation of the other answers, if this is needed in different Composables we can define the following
#Composable
fun RightToLeftLayout(content: #Composable () -> Unit) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
content()
}
}
then simply use
RightToLeftLayout {
ViewToBeChanged()
}
or
RightToLeftLayout {
Row {
...
}
}

Related

how to change paddings in dialog window in jetpack compose?

I need to write a composable function that, like a dialog window, will be displayed over the rest of the screen elements. I wrap the contents of my composable function in Dialog(). But there are paddings on all sides of the screen. How can they be removed?
screenshot of problem, red lines are paddings that need to be removed
I use dialog in my function something like this:
#Composable
fun MyFunction(){
Dialog(onDismissRequest = { }) {
//content
}
}
You can do this:
#Composable
fun MyFunction(){
Dialog(onDismissRequest = { },
properties = DialogProperties(usePlatformDefaultWidth = false)) {
Box(modifier = Modifier.fillMaxSize()) {
//content
}
}
}

Remove LazyColumn overscroll effect in Jetpack Compose

I am using version 1.1.0-alpha05 of Jetpack Compose and I wanted to know if there is a way to turn off the scrolling effect for LazyColumn like xml (android:overScrollMode="never")?
You can disable it by providing LocalOverscrollConfiguration:
CompositionLocalProvider(
LocalOverscrollConfiguration provides null
) {
LazyColumn(Modifier.fillMaxWidth()) {
items(1000) {
Text(it.toString())
}
}
}
You can also build it into your theme so that it applies to the entire application:
#Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: #Composable () -> Unit
) {
val colors = if (darkTheme) {
DarkThemeColors
} else {
LightThemeColors
}
MaterialTheme(
colors = colors,
typography = typography,
shapes = shapes,
) {
CompositionLocalProvider(
LocalOverscrollConfiguration provides null,
content = content
)
}
}
p.s. in 1.2.0-rc01 LocalOverScrollConfiguration has being renamed to LocalOverscrollConfiguration

Modifiers depending on other modifier's values in Jetpack Compose?

How can I create new Modifiers that depend on some other Modifiers' values? Say, for the sake of an example, I want to make the child components's height to be half of the one that is passed in from the parent plus some constant (thus not being able to use fillMaxHeight(fraction: Float)).
#Composable
fun View() {
MyComposable(modifier = Modifier.size(40.dp))
}
#Composable
fun MyComposable(
modifier: Modifier // Assuming this modifier contains a size
) {
Box(modifier) { // Setting the the size from the passed in modifier
val childHeightModifier = Modifier.height(???) // <-- Wanted to be some specific value depending on parent size
Box(childHeightModifier) {
...
}
}
}
You can use BoxWithConstraints for this particular usecase, it provides constraints imposed by parent to its children:
#Composable
fun View() {
MyComposable(modifier = Modifier.size(40.dp))
}
#Composable
fun MyComposable(modifier: Modifier) {
BoxWithConstraints(modifier) { // this: BoxWithConstraintsScope
val childHeightModifier = Modifier.height(maxHeight * 0.5f)
Box(childHeightModifier) {
...
}
}
}
As for communication between Modifiers, there's a ModifierLocal system in the works, which will allow doing exactly that.

How can i add a Toolbar in Jetpack Compose?

I need to add a Toolbar in my Android application with a List like below. I am using Jetpack Compose to create the UI. Below is the composable function i am using for drawing the main view.
#Composable
fun HomeScreenApp() {
showPetsList(dogs = dogData)
}
You can use the TopAppBar.
The best way is to use the Scaffold. Something like:
Scaffold(
topBar = {
TopAppBar(
title = {
Text(text = "TopAppBar")
},
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu,"")
}
},
backgroundColor = ....,
contentColor = ....
)
}, content = {
})
In Jetpack compose Toolbar can be easily implemented by using a Composable function called TopAppBar. You need to place TopAppBar along with your main composable function inside a column.
#Composable
fun HomeScreenApp() {
Column() {
TopAppBar(title = { Text(text = "Adopt Me") }, backgroundColor = Color.Red)
showPetsList(dogs = dogData)
}
}
The above function calls the TopAppBar inside a column followed by your main content view. The TopAppBar function takes in a Text object(Not string) as title. This can also be any Composable function. You can also specify other params like backgroundColor, navigationIcon, contentColor etc. Remember that TopAppBar is just a Composable provided by Jetpack team. It can be your custom function also just in case you need more customization.
Output

How to pass children in Jetpack Compose to a custom composable?

I am curious if it is possible to pass in composables to a custom composables block. Which is then rendered in its definition. I was thinking a vararg + function literal approach could be taken and couldn't find any information.
//definition
#Composable
fun Content() {
Row(modifier = Modifier.fillMaxWidth()) {
//insert a(), b(), ..., z() so that they render in the row
}
}
//usage
Content() {
a()
b()
...
z()
}
Does something like this exist already? You are able to use Jetpack Compose this way. The row implementation must handle the Text somehow.
Row(){
Text("a")
Text("b")
Text("c")
}
After looking at the implementation of Row, RowScope and finding this piece of documentation. This can be achieved by the following code sample. The content function parameter with the type of #Composable() () -> Unit gets passed down into the row.
//definition
#Composable
fun MyCustomContent(
modifier: Modifier = Modifier,
content: #Composable() () -> Unit
) {
Row(modifier = modifier) {
content()
}
}
//usage
MyCustomContent() {
a()
b()
z()
}

Categories

Resources