View(不是 ViewGroup)是否可以包含多个 UI 组件,每个组件都需要 Talkback 支持
Can a View (not ViewGroup) contain multiple UI components that each need Talkback support
背景
我一直在努力剥离一个库,该库使用我在现有应用程序中创建的 Talkback 添加辅助功能。最初我的自定义视图都是 ViewGroups
,所以我使用 ViewGroups
得到了令人惊讶的一切(使用 D-pad 的可聚焦导航、初始视图焦点和内容描述)
当我将其移动到独立库时,我注意到它不适用于 View
。我以为 ViewGroup
是超类,结果发现 View
是超类。所以我一直在努力寻找一些解决方法来解决我的问题。我开始做下面的事情,有一个基于这个方法的问题...
有问题的代码
public class Accessibility {
public static ViewGroupAccessibility with(ViewGroup viewGroup) {
return new ViewGroupAccessibility(viewGroup);
}
public static ViewAccessibility with(View view){
return new ViewAccessibility(view);
}
}
我已经完全实施 ViewGroupAccessibility
并且我打算完全实施 ViewAccessibility
因为它现在是一个存根。到目前为止,下面的代码适用于 TalkBack,我可以用 ViewGroups
做 ViewGroup
相关的事情,看来我可以做 View
相关的事情Views
;但是,我想知道是否需要这样做
我所知道的
Accessibility.with(new RelativeLayout(...)) // Returns ViewGroupAccessibility as RelativeLayout is a ViewGroup
//
...将 return 一个可以处理 ViewGroup
相关内容的 ViewGroupAccessibility
,可以包含许多不同的 View
和 ViewGroup
。 (实际使用方法见post底部代码,有哪些方法可用ViewGroupAccessibility
)
Accessibility.with(new Button(...)) // Returns ViewAccessibility as Button is a View
//
...将 return 一个 ViewAccessibility
只能处理单个 View
相关的东西(这是我的假设)。只想一个Button
.
我不知道的事
// Hypothetical Usage
Accessibility
.with(new ClassThatExtendsView_WithMultipleComponentsThatCanHaveAccessibilitySetOnEachComponentIndividually(...));
// Custom View that extends View
public class ClassThatExtendsView_WithMultipleComponentsThatCanHaveAccessibilitySetOnEachComponentIndividually extends View {
...
}
- 这可能吗?如果没有,那我很好。如果是,那么 I have a lot extra to think about
- 它会 return 一个只能处理单个
View
的 ViewAccessibility
,但那对 return 来说是错误的。
另一种提问方式是我能保证如果用户调用Accessibility.with(View)
给定的视图将始终是单一视图只要?就像一个按钮。或者View可以由多个组件组成
完整代码
您可以在https://codereview.stackexchange.com/questions/134289/easily-add-accessibility-to-your-app-as-an-afterthought-yes-as-an-afterthought处查看代码(原始代码还有一个GitHub link)。我详细介绍了项目的启动方式、我的设计决策和我未来的目标,所有这些都有助于指导代码审查过程。
但是,这里是 用法 的一个片段,我有 ViewGroup
public class ContributionView extends RelativeLayout implements Mappable<Resume.Contribution> {
// Called from Constructors
private void init(AttributeSet attrs, int defStyle) {
root = (ViewGroup) LayoutInflater.from(getContext()).inflate(
R.layout.internal_contribution_view, this, true);
...
// Declare Navigation Accessibility
Accessibility.with(root)
// Disable certain views in the ViewGroup from ever gaining focus
.disableFocusableNavigationOn(
R.id.contribution_textview_creator,
R.id.contribution_textview_year)
// For all focusable views in the ViewGroup, set the D-pad Navigation
.setFocusableNavigationOn(txtProjectName)
.down(R.id.contribution_textview_description).complete()
.setFocusableNavigationOn(txtContributionDescription)
.up(R.id.contribution_textview_name)
.down(R.id.contribution_textview_link).complete()
.setFocusableNavigationOn(txtProjectLink)
.up(R.id.project_textview_description).complete()
// Set which view in the ViewGroup will have be first to be focused
.requestFocusOn(R.id.contribution_textview_name);
invalidateView();
}
private void invalidateView() {
...
// Declare Content Description Accessibility
Accessibility.with(root)
// Set the content descriptions for each focusable view in the ViewGroup
// Set the content description for the Contribution Name
.setAccessibilityTextOn(txtProjectName)
.setModifiableContentDescription(getProjectName())
.prepend("Contribution occurred on the Project called ")
.append(String.format(" by %s in %s",
getProjectCreator(),
getContributionYear())).complete()
// Set the content description for the Contribution Description
.setAccessibilityTextOn(txtContributionDescription)
.setModifiableContentDescription(getContributionDescription())
.prepend("Description: ").complete()
// Set the content description for the Contribution URL
.setAccessibilityTextOn(txtProjectLink)
.setModifiableContentDescription(getProjectLink())
.prepend("URL is ").complete();
}
...
}
是的,有一种方法可以在视图的各种 areas/components 之间移动可访问性。不过,这需要一些工作。
从这里开始:
https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeProvider.html
背景
我一直在努力剥离一个库,该库使用我在现有应用程序中创建的 Talkback 添加辅助功能。最初我的自定义视图都是 ViewGroups
,所以我使用 ViewGroups
得到了令人惊讶的一切(使用 D-pad 的可聚焦导航、初始视图焦点和内容描述)
当我将其移动到独立库时,我注意到它不适用于 View
。我以为 ViewGroup
是超类,结果发现 View
是超类。所以我一直在努力寻找一些解决方法来解决我的问题。我开始做下面的事情,有一个基于这个方法的问题...
有问题的代码
public class Accessibility {
public static ViewGroupAccessibility with(ViewGroup viewGroup) {
return new ViewGroupAccessibility(viewGroup);
}
public static ViewAccessibility with(View view){
return new ViewAccessibility(view);
}
}
我已经完全实施 ViewGroupAccessibility
并且我打算完全实施 ViewAccessibility
因为它现在是一个存根。到目前为止,下面的代码适用于 TalkBack,我可以用 ViewGroups
做 ViewGroup
相关的事情,看来我可以做 View
相关的事情Views
;但是,我想知道是否需要这样做
我所知道的
Accessibility.with(new RelativeLayout(...)) // Returns ViewGroupAccessibility as RelativeLayout is a ViewGroup
//
...将 return 一个可以处理 ViewGroup
相关内容的 ViewGroupAccessibility
,可以包含许多不同的 View
和 ViewGroup
。 (实际使用方法见post底部代码,有哪些方法可用ViewGroupAccessibility
)
Accessibility.with(new Button(...)) // Returns ViewAccessibility as Button is a View
//
...将 return 一个 ViewAccessibility
只能处理单个 View
相关的东西(这是我的假设)。只想一个Button
.
我不知道的事
// Hypothetical Usage
Accessibility
.with(new ClassThatExtendsView_WithMultipleComponentsThatCanHaveAccessibilitySetOnEachComponentIndividually(...));
// Custom View that extends View
public class ClassThatExtendsView_WithMultipleComponentsThatCanHaveAccessibilitySetOnEachComponentIndividually extends View {
...
}
- 这可能吗?如果没有,那我很好。如果是,那么 I have a lot extra to think about
- 它会 return 一个只能处理单个
View
的ViewAccessibility
,但那对 return 来说是错误的。
另一种提问方式是我能保证如果用户调用Accessibility.with(View)
给定的视图将始终是单一视图只要?就像一个按钮。或者View可以由多个组件组成
完整代码
您可以在https://codereview.stackexchange.com/questions/134289/easily-add-accessibility-to-your-app-as-an-afterthought-yes-as-an-afterthought处查看代码(原始代码还有一个GitHub link)。我详细介绍了项目的启动方式、我的设计决策和我未来的目标,所有这些都有助于指导代码审查过程。
但是,这里是 用法 的一个片段,我有 ViewGroup
public class ContributionView extends RelativeLayout implements Mappable<Resume.Contribution> {
// Called from Constructors
private void init(AttributeSet attrs, int defStyle) {
root = (ViewGroup) LayoutInflater.from(getContext()).inflate(
R.layout.internal_contribution_view, this, true);
...
// Declare Navigation Accessibility
Accessibility.with(root)
// Disable certain views in the ViewGroup from ever gaining focus
.disableFocusableNavigationOn(
R.id.contribution_textview_creator,
R.id.contribution_textview_year)
// For all focusable views in the ViewGroup, set the D-pad Navigation
.setFocusableNavigationOn(txtProjectName)
.down(R.id.contribution_textview_description).complete()
.setFocusableNavigationOn(txtContributionDescription)
.up(R.id.contribution_textview_name)
.down(R.id.contribution_textview_link).complete()
.setFocusableNavigationOn(txtProjectLink)
.up(R.id.project_textview_description).complete()
// Set which view in the ViewGroup will have be first to be focused
.requestFocusOn(R.id.contribution_textview_name);
invalidateView();
}
private void invalidateView() {
...
// Declare Content Description Accessibility
Accessibility.with(root)
// Set the content descriptions for each focusable view in the ViewGroup
// Set the content description for the Contribution Name
.setAccessibilityTextOn(txtProjectName)
.setModifiableContentDescription(getProjectName())
.prepend("Contribution occurred on the Project called ")
.append(String.format(" by %s in %s",
getProjectCreator(),
getContributionYear())).complete()
// Set the content description for the Contribution Description
.setAccessibilityTextOn(txtContributionDescription)
.setModifiableContentDescription(getContributionDescription())
.prepend("Description: ").complete()
// Set the content description for the Contribution URL
.setAccessibilityTextOn(txtProjectLink)
.setModifiableContentDescription(getProjectLink())
.prepend("URL is ").complete();
}
...
}
是的,有一种方法可以在视图的各种 areas/components 之间移动可访问性。不过,这需要一些工作。
从这里开始: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeProvider.html