Android çerçevesi, erişilebilirlik gereksinimleri olan kullanıcılara yardımcı olmak için uygulamalardaki içerikleri kullanıcılara sunabilen ve aynı zamanda uygulamaları onlar adına çalıştırabilen bir erişilebilirlik hizmeti oluşturmanıza olanak tanır.
Android, aşağıdakiler de dahil olmak üzere çeşitli sistem erişilebilirlik hizmetleri sağlar:
- TalkBack: Az gören veya kör kullanıcılara yardımcı olur. Bu uygulama, içerikleri sentezlenmiş bir sesle duyurur ve kullanıcı hareketlerine yanıt olarak bir uygulamada işlemler gerçekleştirir.
- Anahtar Erişimi: Bedensel engelli kişilere yardımcı olur. Etkileşimli öğeleri vurgular ve kullanıcının bir düğmeye basmasına karşılık olarak işlemler gerçekleştirir. Cihazı sadece bir veya iki düğme kullanarak kontrol etmenizi sağlar.
Uygulamanızın, erişilebilirlik gereksinimleri olan kullanıcıların uygulamanızı başarılı bir şekilde kullanmasına yardımcı olmak için bu sayfada açıklanan en iyi uygulamalara uyması gerekir. Bu uygulama, Uygulamaları daha erişilebilir hale getirme bölümünde açıklanan yönergelere dayalı olmalıdır.
İlerleyen bölümlerde açıklanan bu en iyi uygulamaların her biri, uygulamanızın erişilebilirliğini daha da iyileştirebilir:
- Etiket öğeleri
- Kullanıcılar, uygulamanızdaki her etkileşimli ve anlamlı kullanıcı arayüzü öğesinin içeriğini ve amacını anlayabilmelidir.
- Erişilebilirlik işlemleri ekleme
- Erişilebilirlik işlemleri ekleyerek, erişilebilirlik hizmetlerini kullananların uygulamanızdaki kritik kullanıcı akışlarını tamamlamasını sağlayabilirsiniz.
- Sistem widget'larını genişletme
- Kendi özel görünümlerinizi oluşturmak yerine çerçevenin içerdiği görünüm öğelerine göre hareket edin. Çerçevenin görünüm ve widget sınıfları, uygulamanızın ihtiyaç duyduğu erişilebilirlik özelliklerinin çoğunu zaten sağlar.
- Renk dışında işaretler kullanma
- Kullanıcılar, kullanıcı arayüzündeki öğe kategorilerini açıkça ayırt edebilmelidir. Bunu yapmak için renklerin yanı sıra desen ve konumu kullanarak bu farkları ifade edin.
- Medya içeriğini daha erişilebilir hale getirme
- Bu içeriği tüketen kullanıcıların tamamen görsel veya işitsel işaretlerle uğraşmak zorunda kalmaması için uygulamanızın video veya ses içeriğine açıklama ekleyin.
Etiket öğeleri
Uygulamanızdaki her bir etkileşimli kullanıcı arayüzü öğesi için kullanıcılara yararlı ve açıklayıcı etiketler sağlamanız önemlidir. Her etiket, belirli bir öğenin anlamını ve amacını açıklamalıdır. TalkBack gibi ekran okuyucular, bu etiketleri kullanıcılara duyurabilir.
Çoğu durumda, bir kullanıcı arayüzü öğesinin açıklamasını öğeyi içeren düzen kaynak dosyasında belirtirsiniz. Etiketleri genellikle uygulamaları daha erişilebilir hale getirme kılavuzunda açıklandığı gibi contentDescription
özelliğini kullanarak eklersiniz. Aşağıdaki bölümlerde başka etiketleme teknikleri açıklanmıştır.
Düzenlenebilir öğeler
EditText
nesneleri gibi düzenlenebilir öğeleri etiketlerken, bu örnek metni ekran okuyucuların kullanımına sunmanın yanı sıra öğenin kendisinde geçerli bir giriş örneği sağlayan metinleri göstermek de yararlı olur. Bu durumlarda, aşağıdaki snippet'te gösterildiği gibi android:hint
özelliğini kullanabilirsiniz:
<!-- The hint text for en-US locale would be "Apartment, suite, or building". --> <EditText android:id="@+id/addressLine2" android:hint="@string/aptSuiteBuilding" ... />
Bu durumda, View
nesnesinin android:labelFor
özelliği EditText
öğesinin kimliğine ayarlanmalıdır. Daha ayrıntılı bilgi için aşağıdaki bölümü inceleyin.
Birinin diğerini açıkladığı öğe çiftleri
EditText
öğesinde genellikle kullanıcıların EditText
öğesine ne girmesi gerektiğini açıklayan karşılık gelen bir View
nesnesi bulunur. View
nesnesinin android:labelFor
özelliğini ayarlayarak bu ilişkiyi belirtebilirsiniz.
Bu tür öğe çiftlerini etiketlemeye ilişkin bir örnek aşağıdaki snippet'te görünür:
<!-- Label text for en-US locale would be "Username:" --> <TextView android:id="@+id/usernameLabel" ... android:text="@string/username" android:labelFor="@+id/usernameEntry" /> <EditText android:id="@+id/usernameEntry" ... /> <!-- Label text for en-US locale would be "Password:" --> <TextView android:id="@+id/passwordLabel" ... android:text="@string/password android:labelFor="@+id/passwordEntry" /> <EditText android:id="@+id/passwordEntry" android:inputType="textPassword" ... />
Koleksiyondaki öğeler
Bir koleksiyonun öğelerine etiket eklerken her etiket benzersiz olmalıdır. Bu şekilde, bir etiketi duyururken sistemin erişilebilirlik hizmetleri, ekrandaki tek bir öğeye referans verebilir. Bu yazışma, kullanıcıların kullanıcı arayüzünde ne zaman geçiş yaptıklarını veya odağı zaten keşfettikleri bir öğeye ne zaman taşıdıklarını bilmelerini sağlar.
Özellikle, her alt öğenin benzersiz bir şekilde tanımlanabilmesi için yeniden kullanılan düzenlerdeki öğelere (RecyclerView
nesneleri gibi) ek metin veya bağlamsal bilgiler ekleyin.
Bunu yapmak için bağdaştırıcı uygulamanızın bir parçası olarak içerik açıklamasını aşağıdaki kod snippet'inde gösterildiği gibi ayarlayın:
Kotlin
data class MovieRating(val title: String, val starRating: Integer) class MyMovieRatingsAdapter(private val myData: Array<MovieRating>): RecyclerView.Adapter<MyMovieRatingsAdapter.MyRatingViewHolder>() { class MyRatingViewHolder(val ratingView: ImageView) : RecyclerView.ViewHolder(ratingView) override fun onBindViewHolder(holder: MyRatingViewHolder, position: Int) { val ratingData = myData[position] holder.ratingView.contentDescription = "Movie ${position}: " + "${ratingData.title}, ${ratingData.starRating} stars" } }
Java
public class MovieRating { private String title; private int starRating; // ... public String getTitle() { return title; } public int getStarRating() { return starRating; } } public class MyMovieRatingsAdapter extends RecyclerView.Adapter<MyAdapter.MyRatingViewHolder> { private MovieRating[] myData; public static class MyRatingViewHolder extends RecyclerView.ViewHolder { public ImageView ratingView; public MyRatingViewHolder(ImageView iv) { super(iv); ratingView = iv; } } @Override public void onBindViewHolder(MyRatingViewHolder holder, int position) { MovieRating ratingData = myData[position]; holder.ratingView.setContentDescription("Movie " + position + ": " + ratingData.getTitle() + ", " + ratingData.getStarRating() + " stars") } }
İlgili içerik grupları
Uygulamanız, doğal bir grup oluşturan birkaç kullanıcı arayüzü öğesi görüntülüyorsa (şarkı ayrıntıları veya bir mesajın özellikleri gibi) bu öğeleri, genellikle ViewGroup
alt sınıfı olan bir kapsayıcı içinde düzenleyin. Container nesnesinin android:screenReaderFocusable
özelliğini true
ve her iç nesnenin android:focusable
özelliğini false
olarak ayarlayın. Bu şekilde erişilebilirlik hizmetleri, içeriğin içindeki açıklamaları tek bir duyuruda art arda sunabilir.
İlgili öğelerin bu şekilde birleştirilmesi, yardımcı teknoloji kullanıcılarının ekrandaki bilgileri daha verimli bir şekilde keşfetmesine yardımcı olur.
Aşağıdaki snippet'te birbiriyle ilişkili içerik parçaları bulunmaktadır. Bu nedenle, ConstraintLayout
örneği olan kapsayıcı öğenin android:screenReaderFocusable
özelliği true
, iç TextView
öğelerinin her birinin android:focusable
özelliği false
olarak ayarlanmıştır:
<!-- In response to a single user interaction, accessibility services announce both the title and the artist of the song. --> <ConstraintLayout android:id="@+id/song_data_container" ... android:screenReaderFocusable="true"> <TextView android:id="@+id/song_title" ... android:focusable="false" android:text="@string/my_song_title" /> <TextView android:id="@+id/song_artist" android:focusable="false" android:text="@string/my_songwriter" /> </ConstraintLayout>
Erişilebilirlik hizmetleri iç öğelerin açıklamalarını tek bir sesle bildirdiği için öğenin anlamını aktarmaya devam ederken her açıklamayı mümkün olduğunca kısa tutmak önemlidir.
Not: Genel olarak, bir grubun alt öğelerinin metinlerini toplayarak bir grup için içerik açıklaması oluşturmaktan kaçınmalısınız. Bu durumda grup açıklaması zayıflar ve bir alt grubun metni değiştiğinde grubun açıklaması görünür metinle eşleşmeyebilir.
Bir listede veya ızgara bağlamında ekran okuyucu, bir listenin veya ızgara öğesinin alt metin düğümlerinin metnini birleştirebilir. Bu duyuruda değişiklik yapmaktan kaçınmanızı öneririz.
İç içe yerleştirilmiş gruplar
Uygulamanızın arayüzü çok boyutlu bilgiler sunuyorsa (ör. festival etkinliklerinin günlük listesi) iç grup kapsayıcılarında android:screenReaderFocusable
özelliğini kullanın. Bu etiketleme şeması, ekranın içeriğini keşfetmek için gereken duyuru sayısı ile her bir duyurunun uzunluğu arasında iyi bir denge sağlar.
Aşağıdaki kod snippet'inde daha büyük gruplardaki grupları etiketlemek için bir yöntem gösterilmektedir:
<!-- In response to a single user interaction, accessibility services announce the events for a single stage only. --> <ConstraintLayout android:id="@+id/festival_event_table" ... > <ConstraintLayout android:id="@+id/stage_a_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage A. --> </ConstraintLayout> <ConstraintLayout android:id="@+id/stage_b_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage B. --> </ConstraintLayout> </ConstraintLayout>
Metin içinde başlıklar
Bazı uygulamalar, ekranda görünen metin gruplarını özetlemek için başlıklar kullanır. Belirli bir View
öğesi bir başlığı temsil ediyorsa öğenin android:accessibilityHeading
özelliğini true
değerine ayarlayarak öğenin erişilebilirlik hizmetleriyle ilgili amacını belirtebilirsiniz.
Erişilebilirlik hizmetlerini kullananlar, paragraflar arasında veya kelimeler arasında gezinmek yerine başlıklar arasında gezinmeyi seçebilir. Bu esneklik, metinde gezinme deneyimini iyileştirir.
Erişilebilirlik bölmesi başlıkları
Android 9 (API düzeyi 28) ve sonraki sürümlerde, ekranın bölmeleri için erişilebilirlik dostu başlıklar sağlayabilirsiniz. Erişilebilirlik amacıyla bölmeler, bir pencerenin içeriği gibi görsel olarak farklı bir bölümüdür. Erişilebilirlik hizmetlerinin bir bölmenin pencereye benzer davranışını anlayabilmesi için uygulamanızın bölmelerine açıklayıcı başlıklar verin. Erişilebilirlik hizmetleri, bir bölmenin görünümü veya içeriği değiştiğinde kullanıcılara daha ayrıntılı bilgiler sağlayabilir.
Bölmenin başlığını belirtmek için aşağıdaki snippet'te gösterildiği gibi android:accessibilityPaneTitle
özelliğini kullanın:
<!-- Accessibility services receive announcements about content changes that are scoped to either the "shopping cart view" section (top) or "browse items" section (bottom) --> <MyShoppingCartView android:id="@+id/shoppingCartContainer" android:accessibilityPaneTitle="@string/shoppingCart" ... /> <MyShoppingBrowseView android:id="@+id/browseItemsContainer" android:accessibilityPaneTitle="@string/browseProducts" ... />
Dekoratif öğeler
Kullanıcı arayüzünüzde yalnızca görsel boşluk veya görsel görünüm amaçlı olan bir öğe varsa android:importantForAccessibility
özelliğini "no"
olarak ayarlayın.
Erişilebilirlik işlemleri ekleyin
Erişilebilirlik hizmetleri kullanıcılarının uygulamanızdaki tüm kullanıcı akışlarını kolayca gerçekleştirmesine izin vermek önemlidir. Örneğin, bir kullanıcı listedeki bir öğeyi kaydırabiliyorsa bu işlem erişilebilirlik hizmetleriyle de gösterilebilir. Böylece kullanıcılar, aynı kullanıcı akışını tamamlamanın alternatif bir yolunu elde ederler.
Tüm işlemleri erişilebilir hale getir
TalkBack, Sesli Erişim veya Anahtar Erişimi kullanıcıları, uygulama içindeki belirli kullanıcı akışlarını tamamlamak için alternatif yollara ihtiyaç duyabilir. Sürükleyip bırakma veya kaydırma gibi hareketlerle ilişkili işlemler için uygulamanız, işlemleri erişilebilirlik hizmeti kullanıcılarının erişebileceği şekilde gösterebilir.
Uygulama, erişilebilirlik işlemlerini kullanarak kullanıcıların bir işlemi tamamlamaları için alternatif yollar sağlayabilir.
Örneğin, uygulamanız kullanıcıların bir öğeyi kaydırmasına izin veriyorsa aşağıdaki gibi özel bir erişilebilirlik işlemiyle de bu işlevi sunabilirsiniz:
Kotlin
ViewCompat.addAccessibilityAction( // View to add accessibility action itemView, // Label surfaced to user by an accessibility service getText(R.id.archive) ) { _, _ -> // Same method executed when swiping on itemView archiveItem() true }
Java
ViewCompat.addAccessibilityAction( // View to add accessibility action itemView, // Label surfaced to user by an accessibility service getText(R.id.archive), (view, arguments) -> { // Same method executed when swiping on itemView archiveItem(); return true; } );
With the custom accessibility action implemented, users can access the action through the actions menu.
Make available actions understandable
When a view supports actions such as touch & hold, an accessibility service such as TalkBack announces it as "Double tap and hold to long press."
This generic announcement doesn't give the user any context about what a touch & hold action does.
To make this announcement more descriptive, you can replace the accessibility action’s announcement like so:
Kotlin
ViewCompat.replaceAccessibilityAction( // View that contains touch & hold action itemView, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK, // Announcement read by TalkBack to surface this action getText(R.string.favorite), null )
Java
ViewCompat.replaceAccessibilityAction( // View that contains touch & hold action itemView, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK, // Announcement read by TalkBack to surface this action getText(R.string.favorite), null );
This results in TalkBack announcing "Double tap and hold to favorite," helping users understand the purpose of the action.
Extend system widgets
Note: When you design your app's UI, use or extend
system-provided widgets that are as far down Android's class hierarchy as
possible. System-provided widgets that are far down the hierarchy already
have most of the accessibility capabilities your app needs. It's easier
to extend these system-provided widgets than to create your own from the more
generic View
,
ViewCompat
,
Canvas
, and
CanvasCompat
classes.
If you must extend View
or Canvas
directly, which
might be necessary for a highly customized experience or a game level, see
Make custom views more
accessible.
This section uses the example of implementing a special type of
Switch
called TriSwitch
while following
best practices around extending system widgets. A TriSwitch
object works similarly to a Switch
object, except that each instance of
TriSwitch
allows the user to toggle among three possible states.
Extend from far down the class hierarchy
The Switch
object inherits from several framework UI classes in its hierarchy:
View ↳ TextView ↳ Button ↳ CompoundButton ↳ Switch
Yeni TriSwitch
sınıfının doğrudan Switch
sınıfından genişletmesi en iyi seçenektir. Böylece Android erişilebilirlik çerçevesi, TriSwitch
sınıfının ihtiyaç duyduğu erişilebilirlik özelliklerinin çoğunu sağlar:
- Erişilebilirlik işlemleri: Erişilebilirlik hizmetlerinin, bir
TriSwitch
nesnesinde gerçekleştirilen her olası kullanıcı girişini nasıl emüle edebileceğiyle ilgili sistem bilgileri. (Şu kaynaktan devralındı:View
.) - Erişilebilirlik etkinlikleri: Ekran yenilendiğinde veya güncellendiğinde
TriSwitch
nesnesinin görünümünün mümkün olan her şekilde değişebileceği tüm erişilebilirlik hizmetleriyle ilgili bilgiler. (Şu kaynaktan devralındı:View
.) - Özellikler: her
TriSwitch
nesnesiyle ilgili ayrıntılar (görüntülediği metnin içeriği gibi). (Şu kaynaktan devralındı:TextView
.) - Durum bilgisi: Bir
TriSwitch
nesnesinin mevcut durumunun açıklaması (ör. "işaretlendi" veya "işareti kaldırıldı"). (Şu kaynaktan devralındı:CompoundButton
.) - Durumun metin açıklaması: Her bir durumun temsil ettiği metin temelli açıklama. (Şu kaynaktan devralındı:
Switch
.)
Switch
ve üst sınıflarının davranışı, TriSwitch
nesneleri için hemen hemen aynıdır. Dolayısıyla, uygulamanızda olası durum sayısını ikiden üçe çıkarmaya odaklanabilirsiniz.
Özel etkinlikler tanımlama
Bir sistem widget'ını genişlettiğinizde muhtemelen kullanıcıların söz konusu widget'la etkileşimde bulunma şekline ilişkin bir özelliği değiştirirsiniz. Erişilebilirlik hizmetlerinin, uygulamanızın widget'ını kullanıcı doğrudan widget'la etkileşimde bulunuyormuş gibi güncelleyebilmesi için bu etkileşim değişikliklerini tanımlamak önemlidir.
Genel bir kural olarak, geçersiz kıldığınız her görüntülemeye dayalı geri arama için ViewCompat.replaceAccessibilityAction()
değerini geçersiz kılarak ilgili erişilebilirlik işlemini yeniden tanımlamanız gerekir.
Uygulamanızın testlerinde, ViewCompat.performAccessibilityAction()
yöntemini çağırarak yeniden tanımlanan bu işlemlerin davranışını doğrulayabilirsiniz.
Bu ilke, TriSwitch nesneleri için nasıl çalışır?
Sıradan bir Switch
nesnesinin aksine, TriSwitch
nesnesine dokunulduğunda üç olası durum döndürülür. Bu nedenle, ilgili ACTION_CLICK
erişilebilirlik işleminin güncellenmesi gerekir:
Kotlin
class TriSwitch(context: Context) : Switch(context) { // 0, 1, or 2 var currentState: Int = 0 private set init { updateAccessibilityActions() } private fun updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label) { view, args -> moveToNextState() }) } private fun moveToNextState() { currentState = (currentState + 1) % 3 } }
Java
public class TriSwitch extends Switch { // 0, 1, or 2 private int currentState; public int getCurrentState() { return currentState; } public TriSwitch() { updateAccessibilityActions(); } private void updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label, (view, args) -> moveToNextState()); } private void moveToNextState() { currentState = (currentState + 1) % 3; } }
Renk dışında işaretler kullanın
Renk körlüğü olan kullanıcılara yardımcı olmak için uygulamanızın ekranlarındaki kullanıcı arayüzü öğelerini ayırt etmek amacıyla renk dışında işaretler kullanın. Bu teknikler farklı şekil veya boyutlar kullanmayı, metin ya da görsel desenler sağlamayı veya öğelerdeki farkları işaretlemek için ses veya dokunma tabanlı (dokunsal) geri bildirim eklemeyi içerebilir.
Şekil 1'de bir etkinliğin iki sürümü gösterilmektedir. Bir sürüm, iş akışındaki iki olası işlemi ayırt etmek için yalnızca renk kullanır. Diğer sürüm, iki seçenek arasındaki farkları vurgulamak için rengin yanı sıra şekilleri ve metni de ekleme en iyi uygulamayı kullanır:
Medya içeriğini daha erişilebilir hale getirme
Video klip veya ses kaydı gibi medya içeriği barındıran bir uygulama geliştiriyorsanız, bu materyali anlama konusunda farklı erişilebilirlik ihtiyaçları olan kullanıcıları desteklemeye çalışın. Özellikle aşağıdakileri yapmanızı öneririz:
- Kullanıcıların medya içeriğini duraklatmasına veya durdurmasına, ses düzeyini değiştirmesine ve altyazıları (altyazılar) açıp kapatmasına olanak tanıyan kontroller ekleyin.
- Video, bir iş akışını tamamlamak için hayati önem taşıyan bilgiler sunuyorsa aynı içeriği transkript gibi alternatif bir biçimde sunun.
Ek kaynaklar
Uygulamanızı daha erişilebilir hale getirme hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın: