toga icon indicating copy to clipboard operation
toga copied to clipboard

Android: setting `background_color` on a box can hide some of its child widgets' UI

Open mhsmith opened this issue 9 months ago • 1 comments

Originally posted in #3118 by @proneon267


if I have:

toga.Box(
            style=Pack(flex=1),
            children=[
                toga.Selection(
                    items=["Alice", "Bob", "Charlie"],
                )
            ],
        )

Then the animation effect on interaction would look like:

But now, if I set a background color on the parent like:

toga.Box(
            style=Pack(flex=1, background_color="#87CEFA"),
            children=[
                toga.Selection(
                    items=["Alice", "Bob", "Charlie"],
                )
            ],
        )

Then the animation effect on interaction would look like:

As we can see, the dropdown arrow is not visible, and the ripple effect is also not visible.

The same problem exists in other widgets also(like toga.Switch, etc.), where the ripple effect will not be visible:

I experimented with semi-transparent backgrounds:

 toga.Box(
            style=Pack(flex=1, background_color=rgba(135, 206, 250, 0.5)),
            children=[
                toga.Selection(
                    items=["Alice", "Bob", "Charlie"],
                )
            ],
        )

Screenshot 2025-01-23 001225

The background features are being drawn directly on the native parent(RelativeLayout), as the Box isn't actually the Selection's parent at the native level: both of them are direct children of the RelativeLayout.

mhsmith avatar Mar 03 '25 15:03 mhsmith

Previous discussion: https://github.com/beeware/toga/pull/3118#issuecomment-2669605322

In summary, we wrapped these widgets in an extra native RelativeLayout on which these features could be drawn. This fixed the issue for widgets with their own background colors, at the cost of causing the ripple effects to be clipped by the wrapper. We accepted this because most of these widgets didn't previously support background colors at all.

But for transparent backgrounds, which are the most common case, clipping the ripple would be a regression. So we implemented transparent backgrounds by setting the wrapper's background to null, which leaves open the possibility that some features might be hidden entirely by the background of a containing Box.

The only other approach I can think of is to actually reproduce the Toga box hierarchy at the native level, rather than making all widgets direct children of the top-level Container.

mhsmith avatar Mar 03 '25 16:03 mhsmith