Android 如何在阅读列表项计数时停止包含页脚行的 TalkBack

Posted

技术标签:

【中文标题】Android 如何在阅读列表项计数时停止包含页脚行的 TalkBack【英文标题】:Android How do i stop TalkBack including footer row when reading list items count 【发布时间】:2017-09-07 04:49:41 【问题描述】:

我有一个包含笔记列表的对话框,我想让用户滚动到列表末尾以找到“确定”按钮以关闭对话框。

对话框包含一个 ListView,我使用页脚行将按钮添加到列表中。

View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).
                inflate(R.layout.list_footer_button, null, false);
listView.addFooterView(footerView);

当我打开回话并打开此对话框时,它读取的 ListView 计数错误,因为它包括页脚行。例如,如果我的列表有 3 项,则对讲显示为“第 1 项,共 4 项”。

问题

我怎样才能让talkBack读取正确数量的项目而忽略页脚行?

如果我无法更改这一点,我该如何创建一个对话框,用户必须滚动到列表末尾才能看到关闭对话框的按钮。

【问题讨论】:

【参考方案1】:

我已通过将按钮添加到最后一行的视图而不是添加页脚来解决此问题。

我的每一行布局都包含一个 textView 和一个按钮,并且按钮设置为“不可见”。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

    <LinearLayout android:id="@+id/notes_details"
        android:orientation="horizontal"
        android:layout_
        android:layout_>
        <!-- other views here but removed for this post -->
        <TextView
            android:id="@+id/notes_text"
            style="@style/notes_text_style"/>
    </LinearLayout>

    <Button
        android:id="@+id/notes_button"
        style="@style/notes_button"
        android:layout_below="@id/notes_details"
        android:layout_centerHorizontal="true"
        android:visibility="invisible" />

</RelativeLayout>

在列表的适配器中,我根据该行是否为最后一行来显示/隐藏按钮

 boolean isLastRow = iPosition == getCount()-1;
 okButton.setVisibility(isLastRow ? View.VISIBLE : View.GONE);

需要更改辅助功能

为了实现无障碍目的,还需要做一些额外的工作。如果没有进行任何更改来支持可访问性,则只有行是可导航的。因此,最后一行将选择注释文本和确定按钮作为一个可选项目,您将无法使用键盘/跟踪球导航到该按钮。

首先您必须设置列表,以便一行中的项目可聚焦

listView.setItemsCanFocus(true);

其次,在适配器的代码中,我在注释 textView 和按钮上相应地设置了 focusable/nextFocusXXX

// when in accessibility mode, we want to set the navigation order for
// the list item's text and the OK button
boolean isLastRow = iPosition == getCount()-1;
if (isAccessibilityEnabled) 
    notesTextView.setFocusable(true);
    okButton.setFocusable(true);
    rowView.setNextFocusForwardId(isLastRow ? R.id.notes_button: R.id.notes_text);
    rowView.setNextFocusDownId(isLastRow ? R.id.notes_button: R.id.notes_text);
    okButton.setNextFocusUpId(R.id.notes_text);

【讨论】:

这有助于我可以将按钮添加到最后一行。但是在某些情况下我不能。我希望能够告诉 TalkBack 在读出计数时不要包含页脚。我觉得奇怪的是 TalkBack 包含页脚,因为页眉和页脚不是实际的列表项,我希望 TalkBack 能够读取项目数 遗憾的是,这种方法不适用于我遇到此问题的 NavigationDrawer。【参考方案2】:

我有另一个与此问题相关的用例。

要求

我有一个包含项目列表的屏幕,并且屏幕右下方有一个浮动操作按钮 (FAB),允许用户将项目添加到列表中。每行的右侧是一个按钮,显示该行项目的选项。

我需要 FAB 不覆盖列表中的最后一行,否则我永远无法单击最后一行的右侧按钮,因为它将位于 FAB 下方。

解决方案及其问题

我尝试了几种解决方案。一个是向列表项添加额外的计数,当获取最后一行的视图时,我返回一个空视图,即 FAB 的高度。我还尝试将此空填充行添加为列表页脚。在这两种情况下,TalkBack 都会读取列表中的项目数。

我无法将我为这个问题发布的解决方案用于我的笔记列表。即使列表中只有 1 或 2 个项目或满屏项目,我也需要 FAB 始终位于屏幕的右下方(而不仅仅是在最后一行之后)。

工作解决方案

将下面代码中的最后 4 个属性添加到我在 xml 布局中的列表定义中似乎可以解决问题。列表中没有添加任何其他项目,因此 TalkBack 可以正确读取列表计数,并确保屏幕左下方的 FAB 不会与最后一行重叠。

<!-- Instead of adding a footer row to stay clear of the FAB,
     add a padding to the listView and set clipToPadding to false
     android:overScrollFooter is set to transparent to avoid having a divider
     for the last item  so there is just white space below the last item -->

<ListView
    style="@style/my_list_style"
    android:layout_alignParentTop="true"

    android:paddingBottom="82dp"
    android:clipToPadding="false"
    android:footerDividersEnabled="false"
    android:overScrollFooter="@android:color/transparent"/>

【讨论】:

以上是关于Android 如何在阅读列表项计数时停止包含页脚行的 TalkBack的主要内容,如果未能解决你的问题,请参考以下文章

单击列表项时如何识别关联的小部件?

在屏幕底部设置 Android 抽屉式菜单页脚

手机间隙应用程序中的页眉和页脚消失了吗?

如何在使用 itertools.groupby 删除重复项时包含每个字符的计数

单击列表视图项

向列表视图添加页脚时出现Indexoutofbound异常[重复]