Android中的辅助功能实现问题

时间:2013-12-09 09:30:27

标签: android accessibility android-a11y

我正在开发查看书籍的应用程序。有一个显示书籍的屏幕(活动)。它具有自定义视图,类似于ViewSwitcher,每个页面都是由自定义视图呈现的位图。

现在我应该实现辅助功能 - 应该通过电话(音频)读取书籍。

我在这里阅读了https://developer.android.com/guide/topics/ui/accessibility/index.html的辅助功能部分,但不够清楚。

我使用SupportLibrary进行可访问性管理,现在我在ViewGroup(管理书页)中使用了此代码。 代码1

private class EditionPagesViewSwitcherAccessibilityDelegate extends AccessibilityDelegateCompat {

    private int mPageCount;
    private double[] mPageRange;

    @Override
    public void onInitializeAccessibilityEvent(final View host, final AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);
        event.setClassName(EditionPagesViewSwitcher.class.getName());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            event.setScrollable(canScroll());
        }
        if (event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_SCROLLED && updatePageValues()) {
            event.setItemCount(mPageCount);
            // we use +1 because of user friendly numbers (from 1 not 0)
            event.setFromIndex((int) (mPageRange[0] + 1));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                event.setToIndex((int) (mPageRange[1] + 1));
            }
        }
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(final View host, final AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
        info.setClassName(EditionPagesViewSwitcher.class.getName());

        info.setScrollable(canScroll());
        info.setLongClickable(true);
        if (canScrollForward()) {
            info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
        }
        if (canScrollBackward()) {
            info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
        }
    }

    @Override
    public boolean performAccessibilityAction(final View host, final int action, final Bundle args) {
        if (super.performAccessibilityAction(host, action, args)) {
            return true;
        }
        switch (action) {
            case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD: {
                if (canScrollForward()) {
                    showNext();
                    return true;
                }
            }
            return false;
            case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD: {
                if (canScrollBackward()) {
                    showPrevious();
                    return true;
                }
            }
            return false;
        }
        return false;
    }

以下是来自网页视图的代码代码2

    @Override
    public void onInitializeAccessibilityEvent(final View host, final AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);

        event.setClassName(EditionPageView.class.getName());
        if (hasText()) {
            event.getText().add(getPageRangeText());
            final String trimText = mSurfaceUpdateData.getPageText().trim();
            if (trimText.length() > MAX_TEXT_LENGTH) {
                event.getText().add(trimText.substring(0, MAX_TEXT_LENGTH));
//              event.getText().add(trimText.substring(MAX_TEXT_LENGTH, trimText.length()));
            }
            else {
                event.getText().add(trimText);
            }
        }
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(final View host, final AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);

        info.setClassName(EditionPageView.class.getName());
    }

因为页面文本数据加载异步第一次可访问性在执行onInitializeAccessibilityEvent代码时没有任何文本。然后,当加载数据时,我触发了AccessibilityEvent.TYPE_VIEW_SELECTED和AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED事件。然后onInitializeAccessibilityEvent再次执行并打电话“读取”书籍文本。

所以我的问题:

  1. 我的辅助功能实现是否合适?可能是设计错了?因为我没有找到关于此功能的任何好的教程。
  2. 为什么我需要在代码1中的支持实现中使用SDK版本检查?为什么支持实现无法正确处理?
  3. 是否真的需要触发TYPE_VIEW_SELECTED和TYPE_VIEW_TEXT_CHANGED?或者可能是其他一些代码应该实现?
  4. 主要问题。在代码2中有评论代码行。此代码语句子字符串文本小于MAX_TEXT_LENGTH(它是3800),因为如果文本更大,则不播放任何内容。没有。是可访问性限制吗?任何其他小于此值的文本都可以很好地播放。
  5. 有谁知道我在哪里可以找到任何好的教程? (是的,我看过样品)。
  6. 有没有人可以通过任何自定义实现来查看?
  7. 已更新

    好。以下是一些答案:

    1. 如果您不希望在获得此文本后立即阅读,则可以看到TYPE_VIEW_SELECTED和TYPE_VIEW_TEXT_CHANGED事件。
    2. 在Nexus 7上,所有大文字都播放得很好(文本最多8000个符号),所以这个问题不会重现,但在三星Galaxy Tab 10.1(Android 4.0.4)和带有Android的Tab 10.1的Genymotion模拟器上4.3的确如此。这很奇怪......

2 个答案:

答案 0 :(得分:1)

4 ..根据String.substring()的文件 您传递的第一个参数是原始字符串中的开始索引,第二个参数是原始字符串中的结束索引

示例:

String text = "Hello";
partOfText = text.substring(2,text.length() - 1);

partOfText等于“llo”(第一个字符是索引0)

因此,通过将常量MAX_TEXT_LENGTH作为第一个参数,它将从索引3800开始取出子字符串。

http://developer.android.com/reference/java/lang/String.html#substring(int)

答案 1 :(得分:0)

你是对的MAX_TEXT_LENGTH是3800.

关于你的疑问,

此代码:

 event.getText().add(trimText.substring(MAX_TEXT_LENGTH, trimText.length()));
        }

你正在尝试子串" trimText"从MAX_TEXT_LENGTH到trimText.length()! 假设trimText =" STACK",trimText.length()= 5,那么trimText.substring(3800,5)将会是什么?

起初,这没有意义,正确使用会是这样的: trimText.substring(0,2)=" ST&#34 ;;