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

Android How do i stop TalkBack including footer row when reading list items count

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

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

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

当我打开回话并打开此对话框时,它读取了错误的 ListView 计数,因为它包括页脚行。例如,如果我的列表有 3 个项目,则对讲显示为 "Item 1 of 4".

问题

如何让 talkBack 读取正确数量的项目而忽略页脚行?

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

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

我的每行布局包含一个 textView 和一个按钮,按钮设置为 "invisible"。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <LinearLayout android:id="@+id/notes_details"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!-- 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>

在列表的适配器中,我show/hide按钮基于该行是否是最后一行

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

需要更改辅助功能

为了使这一切都适用于可访问性目的,还进行了额外的工作。如果没有更改以支持可访问性,则只有行是可导航的。因此,最后一行将 select 备注文本和确定按钮作为一个 select 可用项目,您将无法使用 keyboard/trackerball.

导航到该按钮

首先你必须设置列表,使一行中的项目成为焦点

listView.setItemsCanFocus(true);

其次,在适配器的代码中,我相应地在注释文本视图和按钮上设置了 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);
}

这个问题我还有另一个用例。

要求

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

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

解决方案及其问题

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

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

工作解决方案

将下面代码中的最后 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"/>