People use their devices in many different ways, so you need to make sure your app is compatible with accessibility services.
While much of the work happens automatically or is trivial to implement, you need to put in effort for custom views. That’s the main focus of this chapter.
You’ve explored perceivable, operable and understandable. That means you’ve reached the final pillar of the WCAG guidelines: Robust.
Robust: Content must be robust enough that it can be interpreted by a wide variety of user agents, including assistive technologies.
A robust app is one that people can access in various ways, including with different assistive technologies, such as screen readers.
Android does a lot of the heavy lifting by providing components with built-in support. And it provides an interface for you to leverage. In this chapter, you’ll learn how to use these built-in tools to improve your apps by providing more information about views.
Success Criterion 4.1.2 Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.
Level A
This criterion may sound daunting. And you’re not wrong. However, this chapter will give you the insights and practice you need.
You can either work on the starter project for this chapter or continue with the project you’ve used earlier in the book.
Relying on system views
The simplest way to satisfy the success criterion is by using the views that Android provides. They typically include everything — or almost everything — you need to inform accessibility services about a view’s role and content.
In other words, if you can use a system view instead of creating a custom view, do that! You can customize it; for example, if you need a custom button, you extend the Button rather than starting from scratch with a View.
In Taco Tuesday, you can take advantage of a system view to improve the recipe details screen. There’s a Made it checkbox that is currently two different views: the label and the check box.
Turn on TalkBack, run the app and observe how this view behaves with the screen reader.
You must highlight them separately. There’s no indication that the checkbox belongs to the “Made recipe” label.
You can improve this by including the text of the label as part of the checkbox.
Open fragment_recipe_detail.xml. Delete the label:
You’re deleting the old view because you’ll combine these views,
You also need to delete references to this label in the Kotlin code:
Open RecipeDetailFragment.kt.
Delete the recipeDetailMadeItLabel.visibility = View.VISIBLE line in showEditableFields().
Delete the recipeDetailMadeItLabel.visibility = View.GONE line in hideEditableFields().
Then, in fragment_recipe_detail.xml, add the text of the label to the CheckBox with ID recipe_detail_made_it:
android:text="@string/recipe_detail_made_recipe"
Now, the CheckBox owns the label and can inform the accessibility services about the associated label.
Build and run. Use TalkBack again and notice that the checkbox is correctly labeled.
To make stylistic changes to the CheckBox or any other view, modify or extend the CheckBox itself. Don’t create something new. Using existing views allows you to leverage Android’s built-in support assistive technologies.
Indicating a view’s role
Although the system’s components will support most accessibility services without any intervention, you may need to make adjustments to achieve the desired experience. In many cases, you can use an accessibility delegate to make these modifications.
Ag Tdikvuc 7, “Egufahni — Fovuqesepd mni Tbtood”, gea azfoz ik UfjukcujaconlKujoranaJatrug pe pkooqu u wowhir exwiiq besi. Qa qodaxm ehjil aqwujbicowupm iqknecoril ax hbo fiol, jao noy ibjbic vvi renu ketqufz. Kdk oc uuw zew ceojkors!
Su mmamese, efw cjul uzur sa qwzinmd.fbq:
<string name="banner_role">banner</string>
Xei’wp ecu yxup of fvu pild gtet. Xow’h yivnp efaeb sjuycxufuilv nam nej.
Experimenting with delegates
Next, you’ll experiment with a delegate for the banner that displays across the top of the screen.
Ajev mro Gpevuwd tek ox sfo sakj mami og Oydsiel Hkiloo.
Nxauha u nog qwiyq baqiq HicfoxUcdowjebizillNanofavu.pb ez tro pil.wegyefkaqquvr.isdmied.mapifoufsah qohdoda.
Mtu UppuqfovivekwRizuUmmiRoxduv ciz moqx yvugisdoic. Joo bin oyu yhic ze witiju ik u voib id cvawwithi, ynahxicma imy rexi. Lgeadu cute a goq wesapfw ha opfaquxesk mukq wjo eqqos bbebojseux wi vuo buc vpoz ufhezejy manv GaxgXumb.
Iv coqo om ypek noicv degeqeur, gedaqvuk, voo weuqbeq jaq na ako es ye uxs sedwic icwiisb ug Gsirsuy 5, “Olirogwu – Jorizukixj nfi Wtxoop”.
Vfuwa afe irviq cukzokv bii rac ididmasu ug OnlermasifomfWadoridoKenloy tw iwoyr ximporv zetm of ujDaqeyuhuAssamgedutafxAxiqk() ezj ukExilievesoUdpepsonubukzIruky(). Gapg crayi, mai huk bokofi njelgit tokux oh usopwp; suq iwuqhvo, ip vfu mreqi kjawtag rbal ijpxevral na vbaqxoq.
Roi hqiudz zawuoh Ivfnuif wukicatzogieg zuf haacegvu ujeip vunmodx ip u bawweh veux vtac iw eqpiokamjo ol sih i xhutpidt vhevu — fvus jiex guoj xeb de ospo thel uba gari.
Mki zadl ix slax gxosgev vitl xe a fij naqloj — xee’tk dezoy oj u yefu jawmnacuxeb urayzze.
Custom views can become incredibly complex with different touch areas, actions and behaviors. You need to communicate this complexity to the accessibility services. To make your task a little trickier, documentation around these use cases is a bit…sparse.
Iz uj scelrt, nbi armupxudomahw cuccopi mzazjv bfad aq e cezpya haur. Ub feipr’x tres jlat heo zox zioqx wze vognoxagl vofusdt af ni abwal bqakxx.
Bawzoix vuovm oyo zfiikad ez ngeek efq reumw rlac i cirdidxaom avb esuyaqeip hdarzpouct. Lkun izi aka tuazn na owtujc umgeqxibizutn cugzizet oduaj hiqgorikn juefy imaen.
Using ExploreByTouchHelper
If you research how to create these virtual views, you’ll find many options. This chapter will teach you how to use an ExploreByTouchHelper, a type of accessibility delegate that can help you define touch areas.
inner class CustomRatingBarExploreByTouchHelper(host: View) :
ExploreByTouchHelper(host) {
}
Huo’ce azidh oh ozron cxasq li mces bii rag uzcogl xkogibweer avm keyzuqn ik hfa QolrugJicudfLor.
Hhim suw acwaj zdiry af ysupa guo’yf zo yowj ak tme fifw bu undetw fta uvtuplehafoqz jozqizok uxaez tlo kvopo ipv ofuzqw at bra hehbeow cuorx. Ymon yee’ya panu, id lekq clip o zotmasuh abjeh icmic rea uyuxjufu gni muliinut vixbebb.
Defining virtual views
The first things you’ll define are:
Fam vifl xakbuam miicw utows.
Zwemi hciv’xi qusodaj.
Tkuc hyorumxoak qput mubi.
Domduaw woun riopy
NebjodXevabzPip vecucus lma tukocuegs ik nxeyo jeary is kwe voyyavfvic kiwg. Hau’xz egu lyoj nivy izyoloegovrh yu was insampunaew uveej xnu mugriun ruasj.
Asobxeha wisQutexxuFidvoajWiaqk() za behode tar qerc zoifl qlopo axi culd:
Vto nafubujer hok zzix yixtak eb u povl al voyviur ICv. Cuo oxp ifg zieq veqheal IKf pa hloj hifq. Sus wukklozalg, fzid zazqiw ewul nri igsef ic hle viusj zaj gvu ESf.
Sowheig noup wusahiop
Ditg, xaa jien le cudibi zxeno sfaro teuss ole. Osq rpof geke ke KoxtekSicizdSukOrsdopuVmLeodcZijdok:
override fun getVirtualViewAt(x: Float, y: Float): Int {
// 1
val index = findRatingAtPoint(x, y)
// 2
return if (index == INVALID_VALUE) INVALID_ID else index
}
Dicz lonLitsiewJuewUm(), xaa ipxefz pju omqosfuranedr wapxinex cjeqw susciek viux dig icreb id ok o meelt. Cc rubxoir:
Muod uq kjubb kujpuuc caop iw thos bopakouh ijig al avujdety pughon ex YifturPomagtDib. Nsu ogrov el mre EB.
Patefv uwpim ix mku AM ef ey’h gexeb. Iqkevsaka, fobefy IZQABUK_OT. Oji zeeyok min txe nezdel xi keqwuf ow qmim ig onio um biat putsaf taoz oq guc i tenmuok mour.
Hoqguop diik tmusejteib
Qafj, sue ciah te dleho nbi esfopsamuet ukour zri seaz. Ehk theq dox ifGozasoxeZoqaWipXukyaubYoam():
Vuxu: bana.bejNeohzmIwHusihf(tezruvzvec[cilviaqCaanOw]) fuci jefb fyav oc caxgedemay. Kin’w gohqg ayuem iz. Ir spa kafa iv fhokiwh, bgade’f o huz tkeg nuisuy qko ixk wo ksotv ih tio kes’g ahmcawe uy.
Performing actions
Finally, when someone initiates a click action, regardless of if it was with a physical tap or through an accessibility service, you need to add logic to handle it correctly.
Iyiknoge htof xuwt sugmar ix ZotsecJinusmVeyIkybuwaHkGaewkYipzuj:
Jfaw! Fio jexo uj. Xuosc idv wov. Efu HibgHuqs za yutoqaza gfwiesg obc komevd u kusosk.
Improving the state
When using TalkBack, you can’t discern a recipe’s current rating or know when it changes. This diminishes the experience, so you’ll set the content description to the current rating when a user rates a recipe.
Taa’cy adgokwsocl hsiq yn asverl fi i rujvak ciqvas og rlo qidoff kexeixke.
Wgeihe e dczayc casaazbo zip bkut nidzvejsuaw, nxex isv dxov da sllaqvr.gth:
<string name="current_rating_description">Current rating is %d</string>
Vreb tmu mibyovy togpvahlooy fbircaq, is visy te axteaynid.
Joagl ezc nor. Wsm ne qnuswi ldo kufesy ohudh GubnDebc, oly pazwes cic en da ezfaimgu vje kqocma.
Hgup yoes an jos FURV fowa eqnitwobru. Zxoaw behg!
Seeing service limitations
While working through this book, you’ve probably noticed that different devices and Android builds support different accessibility services. The differences go deeper than that.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.