Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Android Accessibility

1,242 views

Published on

Android Accessibility

Published in: Technology
  • Be the first to comment

Android Accessibility

  1. 1. Android Accessibility Ascii @ KKBOX https://www.facebook.com/asciiss
  2. 2. Accessibility Screen reader (TalkBack) Braille support (BrailleBack) 放大手勢 (連敲 3 下) 輕觸並按住的延遲時間 (for 技體障礙) more ...
  3. 3. TalkBack 起始畫面 Android 4.0 用手指畫矩型 Android 4.1 以上雙指長按 設定 協助工具 -> TalkBack
  4. 4. 快速啟動 TalkBack 步驟一:按住電源鍵直到聽見音效 步驟二:雙指觸碰螢幕直至聽見音效
  5. 5. TalkBack 常用手勢 選擇 (Hover):單擊 開啟 (Click):雙擊 捲動:雙指向上、下、左、右滑動 選擇上 or 下一項:單指向上、下、左、右滑動 回主畫面:單指上滑 + 左滑 返回:單指下滑 + 左滑 最近畫面:單指左滑 + 上滑 Notification:單指右滑 + 下滑
  6. 6. Labeling User Interface Elements android:contentDescription TextView ( contentDescription > text > hint ) ImageView ImageButton CheckBox android:hint EditText ( text > hint > contentDescription )
  7. 7. Enabling view focus setFocusable() isFocusable() requestFocus() android:nextFocusDown android:nextFocusLeft android:nextFocusRight
  8. 8. Common Issues Demo https://github.com/AsciiHuang/AndroidAccessibilityPractices
  9. 9. ArrayAdapter listView.setAdapter(new ArrayAdapter<String>( getActionBar().getThemedContext(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, new String[] { “Custom View”, “Bad List”, “Grid And Navigation”, })); // How to set android:contentDescription attribute ?
  10. 10. BaseAdapter @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate( android.R.layout.simple_list_item_activated_1, parent, false); } ((TextView) convertView).setText(drawerItems[position]); convertView.setContentDescription(drawerItemDescriptions[position]); return convertView; }
  11. 11. Basic Accessibility public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = new ViewHolder(); getViewHolder(convertView); viewHolder.title.setText(Constant.Titles[position]); viewHolder.subTitle.setText(Constant.SubTitles[position]); String strDescription = String.format("%s, %s, %s", Constant.Titles[position], context.getString(R.string.artist), // 歌手 or Artist Constant.SubTitles[position]); convertView.setContentDescription(strDescription); return convertView; }
  12. 12. AccessibilityNodeInfo setFocusable setScrollable setCheckable AccessibilityEvent setChecked setItemCount setFromIndex Custom View
  13. 13. Custom View AccessibilityDelegate sendAccessibilityEvent dispatchPopulateAccessibilityEvent onPopulateAccessibilityEvent onInitializeAccessibilityNodeInfo onInitializeAccessibilityEvent
  14. 14. Custom View public class CustomView extends View { … ... @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); } … ... }
  15. 15. Custom View public class CustomView extends View { public CustomView(Context context, AttributeSet attrs) { super(context, attrs); setAccessibilityDelegate(new CustomDelegate()); } } public class CustomDelegate extends View.AccessibilityDelegate { @Override public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) { return super.dispatchPopulateAccessibilityEvent(host, event); } }
  16. 16. AccessibilityDelegate private AccessibilityDelegate accessibilityDelegate = new AccessibilityDelegate() { @Override public void sendAccessibilityEvent(View host, int eventType) { // 計算 currentIndex } @Override public boolean dispatchPopulateAccessibilityEvent(View, AccessibilityEvent) { int type = event.getEventType(); if (type == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) { event.getText().add("總共 10 項, 目前顯示第 " + (currentIndex + 1) + " 項."); } return super.dispatchPopulateAccessibilityEvent(host, event); } };
  17. 17. AccessibilityNodeInfo protected int currentIndex = 0; public void sendAccessibilityEvent(View host, int eventType) { if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) { currentIndex = mHScrollView.getScrollX() / 900; } super.sendAccessibilityEvent(host, eventType); } public boolean dispatchPopulateAccessibilityEvent(View host,AccessibilityEvent event) { if (event.getEventType() == TYPE_VIEW_ACCESSIBILITY_FOCUSED) { event.getText().add("向左或向右滑動可選擇不同圖片"); } return super.dispatchPopulateAccessibilityEvent(host, event); }
  18. 18. AccessibilityNodeInfo public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { event.setScrollable(true); event.setItemCount(10); event.setFromIndex(currentIndex); super.onInitializeAccessibilityEvent(host, event); } public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { info.setScrollable(true); super.onInitializeAccessibilityNodeInfo(host, info); }
  19. 19. AccessibilityNodeInfo private boolean mChecked = false; public View onCreateView(LayoutInflater, ViewGroup, Bundle) { btn.setOnClickListener(onChangeContentBClicked); btn.setAccessibilityDelegate(buttonAccessibilityDelegate); } private View.OnClickListener onChangeContentBClicked = new View.OnClickListener() { @Override public void onClick(View v) { mChecked = !mChecked; } };
  20. 20. AccessibilityNodeInfo private AccessibilityDelegate buttonAccessibilityDelegate = new AccessibilityDelegate() { @Override public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { super.onInitializeAccessibilityEvent(host, event); event.setChecked(mChecked); } @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); info.setCheckable(true); info.setChecked(mChecked); } };
  21. 21. announceForAccessibility public boolean onHoverEvent(MotionEvent event) { int currentPos = getBlock(event.getX(), event.getY()); if (currentPos != prePos) { prePos = currentPos; if (currentPos == 0) { announceForAccessibility("左上方"); // API 16 } else if (currentPos == 1) { announceForAccessibility("左下方"); } ... } return super.onHoverEvent(event); }
  22. 22. Reference https://github.com/aduggin/android-accessibility https://www.youtube.com/watch?v=BPXqsPeCneA https://www.youtube.com/watch?v=q3HliaMjL38 https://developer.android.com/guide/topics/ui/accessibility/index.html http://developer.android.com/design/patterns/accessibility.html https://github.com/googlesamples/android-BasicAccessibility

×