toga
toga copied to clipboard
Android Table does not scroll horizontally
Describe the bug
Since the horizontal scrollview has been removed from the Android implementation of Table, it is not possible anymore to make the table scroll horizontally.
I tried to add the Table into a ScrollContainer, but the horizontal scrolling was still not working.
I then put the Table into a Box along with a very long Label. Then, the window did scroll horizontally, but I did not see more of the Table content than before. All the Table content to the right did not move into view.
_scroller = toga.ScrollContainer(horizontal=True, vertical=False, style=Pack(flex=1))
_scrolling_box = toga.Box(style=Pack(flex=1, direction=COLUMN))
_scrolling_box.add(toga.Label("fdskjfdksfjdkls fjdks fjdklsfjdkls fjdklsfjdklsfjdsfjklds fjklds jfdkls fjklds fjdsfjfklsd fjs fkdsf dsjf dskl kfsd jdkls fjdsklf jdsklfjsfljlsk"))
self._table = toga.Table(
headings=[
_("app.Table.name"),
_("app.Table.systemApp"),
_("app.Table.version"),
_("app.Table.versionCode"),
_("app.Table.location"),
_("app.Table.packageName"),
],
accessors=["appName", "systemApp", "appVersion", "appVersionCode", "appLocation", "appPackageName"],
missing_value="",
style=Pack(flex=1, font_size=G.config["font_size"]),
)
_scrolling_box.add(self._table)
_scrolling_box.add(toga.Label("fdskjfdksfjdkls fjdks fjdklsfjdkls fjdklsfjdklsfjdsfjklds fjklds jfdkls fjklds fjdsfjfklsd fjs fdks fjkdls jfdkls fjdkls fjdkls fjdkls fjds fj"))
_scroller.content = _scrolling_box
self.main_box.add(_scroller)
Steps to reproduce
- add a Table to a ScrollContainer with horizontal=True
- add a lot of colums, so the Table content becomes wider than the screen width
- try to scroll horizontally
Expected behavior
It is possbile to scroll the Table content horizontally
Screenshots
Environment
- Operating System: Android 13
- Python version: 3.9
- Software versions:
- Briefcase: 0.3.15
- toga: 0.3.2.dev1367+g9021f9106
Logs
Additional context
No response
@freakboy3742 I read your ideas for re-implementing Table for mobile devices (https://github.com/beeware/toga/issues/1392)
Sounds very good to me. The question is how soon this could be done. If this still takes a while, I could in the meanwhile do a PR to re-add the horizontal scrollview in the Android implemention again.
@t-arn So... it will take until someone implements it :-)
I can't give a concrete timeline, other than to say that it's not currently on our schedule for this calendar year. However, it is high on my personal todo list, mostly because Tree and Table are two high-profile widgets that don't exist at all on iOS, and are limited on Android at present. I can't make a firm commitment at this time, but I wouldn't be surprised if we look at this in the first half of next year.
@freakboy3742 When you define a width for the table (for example style=Pack(flex=1, width=3000)
, then the horizontal scrolling works and all the table content is shown. The only problem is that it stretches the colums proportionally, so that they are too wide now.
So, the underlying problem seems to be that the current width of the table cannot be evaluated by the Pack mechanism. How does Pack evaluate the width of a Widget?
hmm....self.interface.intrinsic.width
is nowhere set in the Android implementation of Table.
Is this the source of the problem?
Probably not, because we recently added some code to base.py to set a default intrinsic width and height, so widgets only need to override that if they have more specific dimensions.
I think there are some differences between the platforms in how the column widths are adjusted, but they all behave reasonably well (at least for the simple cases covered by the testbed), so it wasn't necessary to fix during the audit.
strange: my_table.intrinsic.width
returns at least 100
I added following rehint method:
def rehint(self):
self.native.measure(
View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED,
)
self.interface.intrinsic.width = self.scale_out(
at_least(self.native.getMeasuredWidth()), ROUND_UP
)
self.interface.intrinsic.height = self.scale_out(
self.native.getMeasuredHeight(), ROUND_UP
)
Now, the table scrolls horizontally and reports a resonable width of at least 670
, but only the headers are shown. Somehow, the table data gets lost
ok, my_table.intrinsic.height
now is 26 which is why no data is shown.
With this rehint method, all table data is shown, but the columns are wider than necessary:
def rehint(self):
self.native.measure(
View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED,
)
self.interface.intrinsic.width = at_least(self.native.getMeasuredWidth())
my_table.intrinsic.width
now is 1757 which is probably too much.
But if I set CSS pixels (with scale_out), the table does not scroll far enough horizontally and not all data is shown.
In other widgets, for example Button
we use scale_out, so why doesn't this work for Table as well??
Are there any news on this bug?
Not as far as I know.