Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Label's updated text won't be displayed on Android unless "refresh()" gets called explicitly #1289

Open
Dominik1123 opened this issue Jun 24, 2021 · 5 comments
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior.

Comments

@Dominik1123
Copy link

Describe the bug

I create a label = toga.Label() whose text I then modify dynamically (based on user input). I do this via label.text = '...'. This works on Linux however the updated text won't show on Android. If I explicitly call label.refresh() then the updated text also shows on Android.

To Reproduce
Steps to reproduce the behavior:

  1. Create a text = toga.TextInput() field and a label = toga.Label(). In the text input's on_change method, just copy the current value of the field to the label via label.text = text.value.
  2. When entering text, it won't show on the label on Android unless label.refresh() is called explicitly.

Expected behavior

The updated text should show automatically.

Environment:

  • Operating System: Ubuntu 20.04 / Android 10
  • Python version: 3.9
  • Software versions:
arrow==1.1.0
binaryornot==0.4.4
briefcase==0.3.5
certifi==2021.5.30
chardet==4.0.0
click==8.0.1
cookiecutter==1.7.3
gbulb==0.6.1
gitdb==4.0.7
GitPython==3.1.17
idna==2.10
Jinja2==2.11.3
jinja2-time==0.2.0
MarkupSafe==2.0.1
mypy-extensions==0.4.3
poyo==0.5.0
pycairo==1.20.1
PyGObject==3.40.1
python-dateutil==2.8.1
python-slugify==5.0.2
requests==2.25.1
six==1.16.0
smmap==4.0.0
text-unidecode==1.3
toga-core==0.3.0.dev27
toga-gtk==0.3.0.dev27
toml==0.10.2
travertino==0.1.3
typed-ast==1.4.1
typing-extensions==3.7.4.2
urllib3==1.26.5
@Dominik1123 Dominik1123 added the bug A crash or error in behavior. label Jun 24, 2021
@paulproteus
Copy link
Contributor

I can repro a bug similar to this - if you use a button to set the text on an Android TextInput, the text does not visually appear to change.

The solution seems to be to change Toga Android's call to Android EditText's setText() to include a TextView__BufferType.EDITABLE. I've prototyped a fix for that, but need to set up a good repro. PR forthcoming in a few days. Thanks for filing this!

@paulproteus
Copy link
Contributor

@Dominik1123 hmm - I just tried to reproduce this again today, and I couldn't. Can you test with this test repo? https://github.com/paulproteus/toga-issue-1289

When I click the button, the label text changes.

Code:

https://github.com/paulproteus/toga-issue-1289/blob/e3001dce0987762a723b63fd6f0d069530949805/repro/src/repro/app.py#L20-L22

Before click:

image

After click:

image

@freakboy3742
Copy link
Member

@paulproteus From the look of it, the text is updating, but the layout isn't reflecting the new shorter length. That is a bug in itself; but is it possible that if the "new" text is longer than the original, the behavior might be different?

@freakboy3742 freakboy3742 added up-for-grabs android The issue relates to Android mobile support. labels Mar 29, 2022
@mhsmith mhsmith mentioned this issue Nov 23, 2022
4 tasks
@freakboy3742
Copy link
Member

@mhsmith Seems like this might be fixed by your recent work in this area; tagging so we don't forget to close this one when we land the fixes you're working on.

@mhsmith
Copy link
Member

mhsmith commented Mar 3, 2023

This will mostly be fixed by #1794, but I'll leave it open for now because there was a corner case where making the text longer updates the layout, and the label actually expands (as shown by its background color), but the text is wrapped at the previous width.

The corner case was discovered at #1708 (review): "The second last slider [in examples/slider] doesn't appear to report correctly for values <0 or >9". Specifically, the number was disappearing from the label when it went out of that range. I found this was because those numbers had more than one character, making the string wider, and the label was cutting off the last word, even though there was plenty of space for it.

The problem was that we're calling measure outside of the normal layout process, and this is breaking some assumptions made elsewhere. Specifically, measure has a cache which is only invalidated when the view calls requestLayout. Normally TextView.setText would call requestLayout, but if the view dimensions are fixed – as they always are with Toga – it assumes a layout is unnecessary and skips it. The result was that TextView.onMeasure, which is the method that makes decisions about line wrapping and truncation, was not being called at all when the text changed.

I was able to fix this by calling requestLayout or forceLayout before measure. With the refactoring in #1794, this could now be applied to all widgets by putting it in Android's Widget.refresh. The if not self.native.getLayoutParams code which exists in most widgets should maybe also move to there.

I never committed any of that because I got diverted onto looking at #1794, and after that was merged, the examples/slider truncation problem wasn't happening anymore. However, the issue was dependent on the exact ordering of labels getting shorter and longer (I shortened some of them while testing to fit on a mobile-sized screen), and it may even be affected by the length of other labels in the same layout. So I'm not confident that the problem is really gone, and it's probably safer to put the requestLayout call in anyway.

For how to test this, see #1824.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior.
Projects
None yet
Development

No branches or pull requests

4 participants