What's the workaround for the magical behaviour of...
# compose
k
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
Could you clarify what you mean by 'workaround' ? You can just manually use
Modifier.weight()
, that's all
BottomNavigationItem
does.
k
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
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
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
You should remove
with(ColumnScope)
and make :
Copy code
@Composable
fun NavigationRailItem
become
Copy code
@Composable
fun ColumnScope.NavigationRailItem
k
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
Oh I see, don't use
Modifier.weight
then 🙂
k
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
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
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
You can set the
verticalArrangement
on
Column
to define the vertical positioning of the elements
You should not use
weight
here
k
Tried that. Didn't work. The moment I remove
weight
whole column is occupied by just one element
m
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
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
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
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
Yes of course, let me know how it goes
k
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