I have two TextViews. Currently, When Talkback is enabled, the user has to swipe twice to read both TextViews. But I want the screen reader to read the TextViews one after another without any user input (Like WhatsApp reading LastSeen and Chat name in one go). How can I achieve this? Any help would be appreciated
You can set the content description to the layout containing these two views and set individual views as not important for accessibility to combine them.
For example:
<LinearLayout …
android:id="#+id/combinedLayout"
android:contentDescription="Last seen / chat name"
<TextView …
android:text="Last seen"
android:importantForAccessibility="no" />
<TextView …
android:text="Chat name"
android:importantForAccessibility="no"/>
</LinearLayout>
Or in code it would be something like:
combinedLayout.contentDescription = "add content description here"
If any elements are clickable, be careful with setting as not important to accessibility, always test to make sure it behaves as you would expect.
Check out my post about common accessibility issues :) https://medium.com/microsoft-mobile-engineering/android-accessibility-resolving-common-talkback-issues-3c45076bcdf6
Related
Android 9 has introduced accessibilityHeading tag, which can be used by talkback to announce the Headings.
https://developer.android.com/about/versions/pie/android-9.0#a11y
Look for Heading-based navigation
In my app I have multiple Textviews in my activity with some Headings
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:accessibilityHeading="true"
android:text="Accessibility Heading 1"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="Message"
android:textColor="#000000" />
But when I run the app, headings are treated as normal textviews only and no special treatment is given by Talkback.
I can swipe left to navigate through all elements.
There is option to swipe up to change mode for talkback announcements. e.g Default, Links, Controls, Headings etc.
When chosen Headings, I expect talkback to announce only headings and to jump from one heading to another but it stays at the same place even after Swipe Left or Swipe Right gesture.
Set both accessibilityHeading and focusableInTouchMode to true. Then, after setting the navigation mode to Headers (you can do this via the up down gesture), swiping up or down navigates you though the headers. Swiping right and left will still allow you to navigate through single items.
I just tried, it work here as expected.
Talkback properly announces textviews as headings and in heading mode I can navigate to them as well.
Please ensure that you are using the latest version of Talkback.
This is quite an old question so may be you may have got the solution since then
I was having the same issue.
In my particular situation it was fixed when I set focusable and focusableInTouchMode to false in the parent view, and true in the TextView.
Inside one of my recycle view adapters, I have a layout which displays an image and a checkbox.
I am adding accessibility to the app, and I want it so that when a user touches a picture, it will get a reading of the image and the current state of the checkbox (as in, "checked" or "unchecked", which is what the accessibility assistant reads, not true or false)
The two separate lines of code which I have used fit my purpose are as follows:
myImageView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
myCheckbox.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
But if I run that call on the click event, the first instruction is cut short and only the second one is heard. So I believe this might not be the way to go. I probably have to use all of the Accessibility classes provided by Android, but I have no clue where to start.
What should I do for the voice feedback to read "Image one, checked... Image two, unchecked".
Additional info:
I cannot use strings to get the wanted value from the checkbox boolean because the app is multilingual and instead of having to get all the string resources I would rather take advantage of the system.
Thank you,
everyone, for your time.
You can combine both items in a linearlayout and/or you can market the "Image one" part as a label for the checkbox. Both examples are shown below and taken from the link below them.
<LinearLayout
android:id="#+id/consumedContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="false"
android:orientation="horizontal">
<TextView
android:id="#+id/coffeeLimitLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_weight="1"
android:labelFor="#id/coffeeLimitValue"
android:text="#string/coffee_limit_label"
android:textAppearance="#style/TextAppearance.AppCompat.Title"/>
https://www.raywenderlich.com/182100/android-accessibility-tutorial-getting-started
I'm new to android. I'm creating an application, which should handle more than 200 settings, mostly Boolean. Settings can be grouped by they type, there are 5 groups. I assume, that users won't like to configure and save each group separately,but would like to configure all the settings and by pressing save -> save all of them at one time, so scenario with having 5 different activities for each setting group doesn't suite.
What I've tried to do, is set up a TabHost, with separate tab for each group. After I've got "more than 80 views" warning, I've split up my layout, and now each group has own layout.xml;
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<CheckBox
android:id="#+id/cbSetting1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/strSetting1" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<CheckBox
android:id="#+id/cbSetting2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/strSetting2" />
</TableRow>
...
</TableLayout>
And I'm inflating those views onCreate:
View setting1View= getLayoutInflater().inflate(R.layout.group1_layout, null);
group1Tab.addView(view);
With this steps done, I'm avoiding "more than 80 views warning", but won't have it impact on performance, when all views are inflated -> activity will have more than 80 views in total?
Next question: should I get references to all CheckBoxes on my views onCreate:
CheckBox setting1 = (CheckBox)setting1View.findViewById(R.id.cbSetting1);
or should reference them on my saving button press, like:
onSaveClick{
Boolean setting1Value = ((CheckBox)setting1View.findViewById(R.id.cbSetting1)).value
}
or in some other way, to have as little performance impact as possible?
Is there any "good pattern", for designing apps with a lot of views?
Thanks in advance!
P.S. I know, that "best practice" questions are not recommended on StackOverflow, but I've tried to ask as defined questions as possible, and, hopefully, my post is showing at least my researching effort on the issue.
Update
My fault not mentioning it earlier - those settings are stored remotely, and are accessed using HTTP requests (using Web-api). Does suggestions about Preference activities/fragments and ListViews fit in this case?
Based on the way you have described your application, it seems like you have many similar views. I would recommend using a ListView in each of your tabs. ListViews very efficiently handle tons of views.
You will need to write a custom adapter for you ListViews, but you can do this cleverly in a way that doesn't call findViewById() all the time (using the ViewHolder pattern).
It is hard to give specific advice because you have not described exactly what these settings items will contain, but this general idea works well when you have long lists of (event potentially slightly different) views. This pattern would work if you want to have a lot of flexibility over you layout. If you want some standard settings behavior, check out PreferenceFragments, or check out Android's settings developer guide.
If its just boolean settings [i.e. Checkbox].
Then I would prefer trying PreferenceActivity, its just like another activity but preferably used for settings functionality. Also there is an easy way to group your settings element, try PreferenceCategory for grouping.
A small tutorial is available here.
CheckBoxPreference is what you need.
Hope this helps!
In my android application I will show user to enter some input values (in main layout) and when presses a button it fetches data from a website(uses AsyncTask). And after fetching i want to display output in a separate layout.
Layout should be like this:
----------------------------
Status: Success
----------------------------
Details are as follows:
----------------------------
Name of cust. ABCDEFG
Age 16
Total days 365
Present 300
Absent 65
Salary 10000
etc..
----------------------------
BACK
----------------------------
For first two rows, a LinearLayout with TextViews in it is in my mind. For last button "BACK", it is going to be displayed in a LinearLayout. For details i am going to use TableLayout. But this details section is dynamic. that is number of rows varies. When user presses "BACK" button he can do a new fetching and details of new fetch will again be displayed.
I am going to use ScrollView for details section to allow users to view contents if there is larger rows. So I can create the layout dynamically by using code. But I donot know what to do when user presses BACK button and again fetches. Will this already created design stays in memory ? Or any better approach or suggestions ? Also the text in first column of the details section may contain larger texts. So what to do there?
I would advice against the use of tableview, have had several problems with it in the past, and in your case a relative layout will do just as well. Example below highlights what you would need for every row of your details.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="TextView" />
</RelativeLayout>
Regarding larger test, assuming the text is long, and not just large font size, you can add
android:ellipsize="end"
to you TextView to make it cut the text if its getting to long, and end it with "...". For that to work you need to tell the first textView1 in the example above to:
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/textView2"
and if you dont want the text cut, just remove the android:ellipsize line.
If you own Android phone you are no doubt have noticed how in the certain apps the keyboard layout can change from the standard issue to digits-only or to have .com or .net special buttons based on the text field input type (e.g. phone number). So I have 2 questions:
how to trigger this customization? I suspect it has to do with EditText format
Can this be taken even further if I want to add some custom buttons to inject a specific pattern? Say I would have an AND button which when pressed will add all uppercase " AND " surrounded by spaces to the text field. Can this be done?
What I'm not asking is how to capture some key combination in onKeyPress event and then populate text field with a pattern - I pretty much know how to do that already.
It is controlled by the android:inputType XML attribute (or the setInputType() method).
For info on the available options see the pages for the XML attribute or the object's method.
As an example, the following XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:text="example text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone" />
</LinearLayout>
will give you this layout:
whereas changing the inputType to textEmailAddress will give you this:
You can customize the "action" button as explained here, but I don't believe there's any way to do full customization of keyboards at this time, but I could be wrong.
The thing that concerns me is that "inputType" is listed as a deprecated property, meaning it may work for a while, but - eventually - Android will stop supporting it. Is there another alternative?
UPDATED: My bad - I'm confusing with inputMethod.