https://kotlinlang.org logo
#compose
Title
# compose
k

Kshitij Patil

11/11/2020, 4:17 PM
What's the workaround for the magical behaviour of Box inside a Row as mentioned in the source of BottomNavigationItem I'm almost done with the integration of Backdrop with Navigation rail and I want to arrange all the navigation items at the top. Currently the Navigation rail is comprised of Custom Layout in a Box in a Column where each box is one Navigation item.
l

Louis Pullen-Freilich [G]

11/11/2020, 5:11 PM
Could you clarify what you mean by 'workaround' ? You can just manually use
Modifier.weight()
, that's all
BottomNavigationItem
does.
k

Kshitij Patil

11/11/2020, 5:35 PM
I'm already using this snippet from
BottonNavigationItem
Copy code
Box(
    with(ColumnScope) {
        modifier
            .selectable(
                selected = selected,
                onClick = onClick,
                interactionState = interactionState,
                indication = ripple
            )
            .weight(1f)
    },
    alignment = Alignment.Center
) {...}
Have tried it with both
ColumnScope
and
RowScope
, nothing changes.
l

Louis Pullen-Freilich [G]

11/11/2020, 6:32 PM
Is this
Box
directly inside a
Column
though? In any case this pattern is not recommended, and if you want your navigation items to only be used inside a column, you should define them as:
Copy code
@Composable
fun ColumnScope.BottomNavigationItem(...) {}
So that way they can only be used inside a
Column
,and you know that the
Modifier.weight
will work correctly
k

Kshitij Patil

11/11/2020, 6:47 PM
Yes, they're already defined as you mentioned. I've put the code on Github, It'd be helpful if you review the code Thanks!
l

Louis Pullen-Freilich [G]

11/11/2020, 6:51 PM
You should remove
with(ColumnScope)
and make :
Copy code
@Composable
fun NavigationRailItem
become
Copy code
@Composable
fun ColumnScope.NavigationRailItem
k

Kshitij Patil

11/11/2020, 7:06 PM
This didn't solve the alignment problem though. I want those items to be aligned at the top and not to distribute the entire height
l

Louis Pullen-Freilich [G]

11/11/2020, 7:07 PM
Oh I see, don't use
Modifier.weight
then 🙂
k

Kshitij Patil

11/11/2020, 7:10 PM
And what should I use for alignment?
Modifier.wrapContentHeight(<http://Alignment.Top|Alignment.Top>)
didn't work. Also, when I remove the
weight
, the entire
navRail
is occupied by only one navigation item
l

Louis Pullen-Freilich [G]

11/11/2020, 7:29 PM
I think this is because the custom layout you are using uses the maxHeight for the layout height, it might be easier to start from scratch rather than trying to modify the existing BottomNavigationItem code here
Or just play aruond with changing the height / width in the custom layout
k

Kshitij Patil

11/11/2020, 8:13 PM
Okay. I'll try to play around and see if I could get this working. I was reusing the BottomNavigationItem code since most of the logic remains the same. Btw, using WindowAssets from accompanist-insets shows the exact opposite behaviour - the entire column collapses into a single cell
m

Mihai Popa

11/12/2020, 2:00 PM
You can set the
verticalArrangement
on
Column
to define the vertical positioning of the elements
You should not use
weight
here
k

Kshitij Patil

11/12/2020, 2:01 PM
Tried that. Didn't work. The moment I remove
weight
whole column is occupied by just one element
m

Mihai Popa

11/12/2020, 2:01 PM
The reason why removing
weight
will cause the first element to get all the height is simply because you size your custom
MockItem
layout to fill the available height
When you do
layout(constraints.maxWidth,constraints.maxHeight)
It means occupy the entire available space
You probably want
layout(constraints.maxWidth, placeable.height)
instead?
k

Kshitij Patil

11/12/2020, 2:04 PM
I've an icon and text inside custom layout. I want them to be vertically center. I'll try use sum of heights of both them
m

Mihai Popa

11/12/2020, 2:05 PM
I'll try use sum of heights of both them
Right (consider you might also want padding between them)
Also what do you mean that you want them to be vertically center?
Did you mean horizontally?
If so, you don't actually need the custom layout (you could just use another Column) if you are not keen to write a custom layout as an exercise
k

Kshitij Patil

11/12/2020, 2:11 PM
I guess the need to write custom layout was some animation stuff (translation, color). Will try to see if that's possible with standard components instead of using a custom layout. Thanks! May I tag you if I've to ask any related question?
m

Mihai Popa

11/12/2020, 2:12 PM
Yes of course, let me know how it goes
k

Kshitij Patil

11/12/2020, 2:34 PM
Thanks @Mihai Popa that really worked. Instead of blindly using
constraints.maxHeight
I set the
height=iconPlaceable.height+labelPlaceable.height+(2*baselineOffset)
and started placing
Placeable
s from
y=0