未触发 dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent not triggered
我正在尝试在我的应用程序中实现辅助功能。我对它的实际工作方式感到困惑。我在不同的包中有一个简单的 imageView,我将事件发送为:
public final void onClick(final android.view.View v) {
android.util.Log.v(CLASSNAME,"onClick tag:"+v.getTag());
v.sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED);
我实现了辅助功能 class 如下:
import android.content.Context;
public final class Accessibility extends android.view.View {
public Accessibility(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public static android.view.accessibility.AccessibilityManager manager = (android.view.accessibility.AccessibilityManager)getSystemService(android.content.Context.ACCESSIBILITY_SERVICE);
public static android.view.accessibility.AccessibilityEvent event = android.view.accessibility.AccessibilityEvent.obtain();
public static Accessibility accessibility;
public static boolean isEenabled()
{
if(manager.isEnabled())
return true;
else
return false;
}
@Override
public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
{
super.dispatchPopulateAccessibilityEvent(event);
android.util.Log.e(CLASSNAME, "Came here");
{
event.getText().add("Click here!!");
event.setEnabled(true);
return true;
}
我阅读了 Developer 文档,我必须重写 View class 中的方法(这就是我将 class 扩展到 View 的原因)。我意识到此方法也存在于 Activity class(即扩展 Activity)中,它调用此方法甚至不发送任何事件。
我知道我在做一些愚蠢的事情,但无法找到确切的位置。
P.S.: 我确实在 v.sendAccessibilityEvent 上设置了一个断点 - 它转到 View.java 并且不知何故它在条件 "AccessibilityManager.getInstance(mContext)!= null"
上失败了
它没有被调用的原因是因为系统调用了你的 ImageView 的 dispatchPopulateAccessibilityEvent(因为你从那里发送事件),而不是你的 Accessibility object.
要实现自定义辅助功能行为,您有 3 个选择:
实现一个扩展 ImageView 的自定义视图(并覆盖 dispatchPopulateAccessibilityEvent 方法和其他辅助功能)。这是一种更通用的方法,可以让开发人员模仿系统小部件的可访问性行为。
这是一个示例 class,它在 TYPE_VIEW_CLICKED
事件上向事件 object 添加了自定义文本。您需要将其 clickable 属性设置为 true 以便它可以接收点击事件。我覆盖了 onPopulateAccessibilityEvent
而不是 dispatchPopulateAccessibilityEvent
因为这个 class 没有 children 并且不需要覆盖调度算法。
public class CustomImageView extends ImageView {
private static final String TAG = CustomImageView.class.getSimpleName();
/* Here are constructors from ImageView */
@Override
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(event);
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
Log.v(TAG, "Populating accessibility event");
event.getText().add("Custom text from onPopulateAccessibilityEvent");
}
}
}
实施AccessibilityDelegate。这不像第一种方法那样通用,但对于简单的应用程序来说,它更容易并且允许更复杂的可访问性行为。
这里有一个 AccessibilityDelegate,其功能与 CustomImageView 类似。主要优点是您可以为不同的 object 和 class 重用相同的 AccessibilityDelegate。
imageView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(host, event);
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
Log.v(TAG, "Populating accessibility event");
event.getText().add("Custom text from AccessibilityDelegate");
}
}
});
如果您需要非常复杂的可访问性逻辑,请结合使用这两种方法。
View 中有很多辅助功能方法,请仔细阅读文档,哪些是您真正需要覆盖的。
我正在尝试在我的应用程序中实现辅助功能。我对它的实际工作方式感到困惑。我在不同的包中有一个简单的 imageView,我将事件发送为:
public final void onClick(final android.view.View v) {
android.util.Log.v(CLASSNAME,"onClick tag:"+v.getTag());
v.sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED);
我实现了辅助功能 class 如下:
import android.content.Context;
public final class Accessibility extends android.view.View {
public Accessibility(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public static android.view.accessibility.AccessibilityManager manager = (android.view.accessibility.AccessibilityManager)getSystemService(android.content.Context.ACCESSIBILITY_SERVICE);
public static android.view.accessibility.AccessibilityEvent event = android.view.accessibility.AccessibilityEvent.obtain();
public static Accessibility accessibility;
public static boolean isEenabled()
{
if(manager.isEnabled())
return true;
else
return false;
}
@Override
public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
{
super.dispatchPopulateAccessibilityEvent(event);
android.util.Log.e(CLASSNAME, "Came here");
{
event.getText().add("Click here!!");
event.setEnabled(true);
return true;
}
我阅读了 Developer 文档,我必须重写 View class 中的方法(这就是我将 class 扩展到 View 的原因)。我意识到此方法也存在于 Activity class(即扩展 Activity)中,它调用此方法甚至不发送任何事件。
我知道我在做一些愚蠢的事情,但无法找到确切的位置。
P.S.: 我确实在 v.sendAccessibilityEvent 上设置了一个断点 - 它转到 View.java 并且不知何故它在条件 "AccessibilityManager.getInstance(mContext)!= null"
上失败了它没有被调用的原因是因为系统调用了你的 ImageView 的 dispatchPopulateAccessibilityEvent(因为你从那里发送事件),而不是你的 Accessibility object.
要实现自定义辅助功能行为,您有 3 个选择:
实现一个扩展 ImageView 的自定义视图(并覆盖 dispatchPopulateAccessibilityEvent 方法和其他辅助功能)。这是一种更通用的方法,可以让开发人员模仿系统小部件的可访问性行为。
这是一个示例 class,它在
TYPE_VIEW_CLICKED
事件上向事件 object 添加了自定义文本。您需要将其 clickable 属性设置为 true 以便它可以接收点击事件。我覆盖了onPopulateAccessibilityEvent
而不是dispatchPopulateAccessibilityEvent
因为这个 class 没有 children 并且不需要覆盖调度算法。public class CustomImageView extends ImageView { private static final String TAG = CustomImageView.class.getSimpleName(); /* Here are constructors from ImageView */ @Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { super.onPopulateAccessibilityEvent(event); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) { Log.v(TAG, "Populating accessibility event"); event.getText().add("Custom text from onPopulateAccessibilityEvent"); } } }
实施AccessibilityDelegate。这不像第一种方法那样通用,但对于简单的应用程序来说,它更容易并且允许更复杂的可访问性行为。
这里有一个 AccessibilityDelegate,其功能与 CustomImageView 类似。主要优点是您可以为不同的 object 和 class 重用相同的 AccessibilityDelegate。
imageView.setAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { super.onPopulateAccessibilityEvent(host, event); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) { Log.v(TAG, "Populating accessibility event"); event.getText().add("Custom text from AccessibilityDelegate"); } } });
如果您需要非常复杂的可访问性逻辑,请结合使用这两种方法。
View 中有很多辅助功能方法,请仔细阅读文档,哪些是您真正需要覆盖的。