I have a lot of dynamically generated TextViews (being fed to a list array adapter), and each of their text contains a summary of a lot of small information. In an effort to improve UI, I used some styling when displaying information, like so:
(4 Votes) ☬ [tag1] [java] [regex] ☬ 2 min ago ☬ author ☬ 245 points
This line is constructed using a StringBuilder. This line (let's say) looks nice, but not friendly to accessibility tools such as "Google Talk Back". It reads like so: "four votes unknown character bracket tag one close bracket..."
So to fix that, I'm generating another string and set it for content description, like so:
Asked by "author", who has "245" reputation points, received "4 votes" since "two minutes ago", these are the tags: "tag1", "java", "regex".
This line would also be generated using StringBuilder, essentially doubles my run-time.
I'm asking:
Is this really doubling my run-time? Is it worth it? Obviously only a very small percentage of people would need accessibility tools, but looks like I'm sacrificing everyone else's CPU cycles.
If it indeed has a negative impact on performance, how can I improve it? Is there a way to detect whether "Talk Back" is used? Is android smart enough to detect this itself, and ignore setContentDescription() line?
I don't think its worth worrying about unless your app has performance issues. But it you do, you can always turn it on or off based on if any accessibility settings are turned on. You can check for enables accessibility apps in Secure Settings.
Related
I would like to make the talkback say a simple mathematical expression like: "2 - (3/5)"
However, when it reads, talkback skips the parentheses, thus affecting the expression to take on a different meaning.
Thanks to #QuentinC I was able to read more questions on the subject. Would this fall under "it's best to leave it at that and not edit" cases, or should I instead be looking for ways to force talkback to speak every character?
I have a full-fledged working Flutter app. Now, I want it to support multiple languages, such as Spanish, Hindi, Urdu, etc. (primarily Indian Languages which are available in Google Translate).
I have searched about this, but all of them mention about "arb files" in which I believe, I have to manually write each and every translated string of the whole app.
I would like to build a package with a class (or just a method) which may require 2 parameters, string and the locale in which translation is required.
Kindly suggest me the best way to achieve it and how can I do it. A link to tutorial would be appreciated.
Flutters own step by step walkthrough to i18n is literally the first result that pops up when you put "Flutter localization" into Google.
https://docs.flutter.dev/development/accessibility-and-localization/internationalization
If for some reason you don't want .arb files, you can roll your own. But be prepared that you will find out along the way what is missing and ending up with a home-brewn solution that is worse than Flutters own to achieve the same thing.
There is no magic function to translate text. Even if you could translate on the fly with a translation service, translation services have become really good in recent years, but they (as any human you could hire) are only as good as the context they get. If they get only single words or half sentences, as is common in an app with headlines and buttons, the result will be horrible. As if you just put every single word into a dictionary. That is not translation. It will feel artificial and laughable.
So... give the existing packages a try. Start with Flutters. It might seem complicated, but it's complicated for a reason.
Why do some Android projects list a "CHAR_LIMIT" in comments above each string in strings.xml? For example, from https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/strings.xml:
<!-- [CHAR LIMIT=25] String for confirmation button to enable a feature gated by the battery saver warning-->
<string name="confirm_battery_saver">OK</string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
<string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
Googling turns up a few other examples, but no explanation. I don't believe Android documentation covers this. And unlike tags like <xliff:g> it doesn't seem to be an official, functional component of Android. My best guess is that it's a convention some projects use to indicate "when you translate this, make sure the translated version doesn't have more than X characters or else it will break the UI!" Or perhaps, vice versa, "if you're using this String, make sure the UI still looks good with a String X characters long"
My thought is that the UI should always be built to be as flexible as is reasonable, given the possibility for translations of different lengths, and the possibility of different text sizes. Also that translators should strive for the translation to be more or less the same size as the original text, instead of going from, say, 10 characters to 50 characters when translating. So I would think this "CHAR_LIMIT" would be completely unnecessary and could be dropped. (I ask, because I'm touching up an old open source project that uses this.)
Is my understanding of "CHAR_LIMIT" correct, or what is it for, and should it be used?
when you translate this, make sure the translated version doesn't have more than X characters or else it will break the UI!" Or perhaps, vice versa, "if you're using this String, make sure the UI still looks good with a String X characters long
That's pretty much my understanding of it.
I searched around a bit for where this clue is used, and I found only a single place: stringslint.py. This is a lint script that seems to be used on strings.xml files. Maybe the project you're talking about used this script? The file docs say:
Enforces common Android string best-practices. It ignores lint
messages from a previous strings file, if provided.
Usage: stringslint.py strings.xml
Usage: stringslint.py strings.xml old_strings.xml
In general:
Errors signal issues that must be fixed before submitting, and are only used when there are no false-positives.
Warnings signal issues that might need to be fixed, but need manual inspection due to risk of false-positives.
Info signal issues that should be fixed to match best-practices, such as providing comments to aid translation.
So that goes along what you were saying. It's a clue for translators but can also be used for lint checks, hence the easily parseable syntax.
I also tried to search for pages explaining how one would translate the Android System, hoping CHAR LIMIT would be mentioned somewhere. But it doesn't seem like the community can contribute their own translation, so I found no such page.
Note that there's also a BACKUP_MESSAGE_ID that's declared in the same way for some string resources. It seems related to the system Settings app, but I don't know any more that than.
EDIT: I found another script using it: https://chromium.googlesource.com/chromium/src/+/master/tools/grit/grit/tool/android2grd.py, although this time it's CHAR-LIMIT.
I'd like some advice regarding Android UI (in)efficiency. I'm trying to determine the best way to build a particular layout for my app, however I think my initial idea potentially runs the risk of brutalising performance. Basically I have three very similar and related app components, and to configure them, I need user input. The three components share different parameters within a global set. I want to determine a nice, fluid fashion in which to display this input form on the device.
What I'd like to do is simply allow users to use one form in place of three. All three components are related/similar and they share some of the configuration parameters the user is required to enter.
My initial idea is as follows:
Build an extensive layout of UI elements necessary for initial display for any of the three instances via XML. Unfortunately, given the number of parameters organised in rows, this will amount to approximately 50 view objects in total in this case.
Create activity so that the user enters the screen, and understands
they are required to initially choose one of three values from a
Spinner widget at the top of the screen.
By using bitwise comparison operators, simply show/hide the various
controls related to the chosen Spinner value. (Triggered via
Spinner's onItemSelectedListener() )
Create some minor/lightweight animations and so on so they
understand pieces of the puzzle are being added or removed to
reflect their choice.
Alternatively, a second theory involves using three different activities, and saving state between the three, passing parameters between them... Perhaps I should abandon my initial idea and use something along those lines? A third alternative?
The primary motivation for doing this instead of just breaking it into three separate forms is it should allow for users to experience a consistent UI with minimal frustration if they choose to re-think their initial selection. Using the above, if a user fills out half of the form and decides they'd like to use an alternative option from the Spinner, their information is obviously retained, because they'd be using the same view objects.
I would like to ask you all for a little advice on how I can achieve this without risking too much of a performance decline on typical, mid-range Android devices (by that I mean handsets most users own, from Froyo up, and in particular those from Gingerbread up). I'm concerned because I only have access to one test device and it's a HTC One X handset, and that's obviously an extraordinarily poor choice for getting a handle on how capably most mortal devices can render more complex layouts.
I'd also appreciate any guidance regarding tips for optimising performance... I understand from scouring the community and Android's developer resources that rendering some layout objects is more exhaustive than rendering others, and I should opt for LinearLayout where possible (as opposed to RelativeLayout for example). Is there any definitive resource for comparing the performance of UI options? I'd very much like to spare you the time and effort, and go and acquire the knowledge myself.
Thanks in advance for the time and effort. Cheers.
Edit: I guess I should mention that if necessary, almost none of these views need to be drawn to the screen when the activity is initially loaded (the first time anyway)... If desired, I can initially load only a few views, and the Spinner widget. It'd be like loading 'No option selected' instead of Option 1, by default. The impact on the user may actually be minor if the device is sluggish because their device won't actually have to draw more than a mere handful of view objects when the activity is loaded. At any one point, the device is probably only required to render and subsequently display about 30 view objects at any one time. I guess the critical issue is, "Will the user experience a hang or a delay if their phone is struggling to load a lot of XML, even if it's not displaying it all when the activity is loaded?"
+1 for great effort on the question. My personal suggestion is that you stick with your second theory. Keep your data separate from the views -- store the entered values somewhere such as SharedPreferences or a database -- and have three different layouts (one for each form). On creating your Activity, check each common field for a previously stored value and populate that field if one exists. Trying to do something like the first list, while maybe clever, would hardly be ideal.
I think it would make more sense to just develop layouts for the different device screens. You can do this, and put different layouts in different folders. Here is a great article that talks about some of this. I wouldn't give people the "option" to choose. They may not always know the answer, so it is best to let the phone decide which layout to use.
Here is the article:
http://developer.android.com/guide/practices/screens_support.html
I'm currently reading books and articles about Test Driven Development, both in the case of Android development and about TDD in general. I'm a bit confused about testing the GUI.
In this book the author writes test even for designing the GUI for an example application. For things like "an EditText's margin should be 5 pixels wide". Does this really make sense? I can understand the value in writing test for specific functions (e.g. does my unit converter app convert 5 meters correctly into inches?), but should I really test if I defined my UI widgets correctly in the layout xml file?
I usually have to develop UIs that are much more complex than the 2-EditTexts-below-each-other scenario. I think it'd be a complete waste of time to write tests to check if I defined the font sizes to be 22dip or not. Am I getting the wrong idea?
Test what you think can break. If you don't think the EditText's margin will ever change - don't worry about it. But think about the ways it could change. Beyond the obvious one of changing the value in the XML, you might decide for the sake of simplicity, consistency, and reduced line count that you want to use styles and themes. Now that individual element's margin can change because its theme changed - or because the theme on which it was based changed, etc.
I think you're right; it sounds like the book (which I haven't read) is choosing a toy example, perhaps for pedagogic clarity. Extending that example to real projects without applying a little common sense adjustment may be inappropriate.