Remove AccessibilityNodeProvider sample code.
This code has been superseded by the ExploreByTouchHelper class in the support-v4 library. Change-Id: I3ff499e3c5f404c9252d967d1a3cb4ff999dfdfb
This commit is contained in:
@@ -995,16 +995,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- Accessibility Samples -->
|
|
||||||
<activity android:name=".accessibility.AccessibilityNodeProviderActivity"
|
|
||||||
android:label="@string/accessibility_node_provider"
|
|
||||||
android:enabled="@bool/atLeastIceCreamSandwich">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.SAMPLE_CODE" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<!-- Application Updating Samples -->
|
<!-- Application Updating Samples -->
|
||||||
|
|
||||||
<!-- BEGIN_INCLUDE(app_update_declaration) -->
|
<!-- BEGIN_INCLUDE(app_update_declaration) -->
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="50dip"
|
|
||||||
android:text="@string/accessibility_node_provider_instructions">
|
|
||||||
</TextView>
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="com.example.android.apis.accessibility.AccessibilityNodeProviderActivity$VirtualSubtreeRootView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" >
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1424,10 +1424,6 @@
|
|||||||
<!-- Accessibility examples strings -->
|
<!-- Accessibility examples strings -->
|
||||||
<!-- ============================ -->
|
<!-- ============================ -->
|
||||||
|
|
||||||
<string name="accessibility_node_provider">Accessibility/Accessibility Node Provider</string>
|
|
||||||
<string name="accessibility_node_provider_instructions">Enable TalkBack and Explore-by-touch from accessibility
|
|
||||||
settings. Then touch the colored squares.</string>
|
|
||||||
|
|
||||||
<string name="accessibility_service">Accessibility/Accessibility Service</string>
|
<string name="accessibility_service">Accessibility/Accessibility Service</string>
|
||||||
<string name="accessibility_service_label">ClockBack</string>
|
<string name="accessibility_service_label">ClockBack</string>
|
||||||
<string name="accessibility_service_instructions">
|
<string name="accessibility_service_instructions">
|
||||||
|
|||||||
@@ -1,484 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.example.android.apis.accessibility;
|
|
||||||
|
|
||||||
import com.example.android.apis.R;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
|
||||||
import android.view.accessibility.AccessibilityManager;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
|
||||||
import android.view.accessibility.AccessibilityNodeProvider;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This sample demonstrates how a View can expose a virtual view sub-tree
|
|
||||||
* rooted at it. A virtual sub-tree is composed of imaginary Views
|
|
||||||
* that are reported as a part of the view hierarchy for accessibility
|
|
||||||
* purposes. This enables custom views that draw complex content to report
|
|
||||||
* them selves as a tree of virtual views, thus conveying their logical
|
|
||||||
* structure.
|
|
||||||
* <p>
|
|
||||||
* For example, a View may draw a monthly calendar as a grid of days while
|
|
||||||
* each such day may contains some events. From a perspective of the View
|
|
||||||
* hierarchy the calendar is composed of a single View but an accessibility
|
|
||||||
* service would benefit of traversing the logical structure of the calendar
|
|
||||||
* by examining each day and each event on that day.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class AccessibilityNodeProviderActivity extends Activity {
|
|
||||||
/** Called when the activity is first created. */
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.accessibility_node_provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class presents a View that is composed of three virtual children
|
|
||||||
* each of which is drawn with a different color and represents a region
|
|
||||||
* of the View that has different semantics compared to other such regions.
|
|
||||||
* While the virtual view tree exposed by this class is one level deep
|
|
||||||
* for simplicity, there is no bound on the complexity of that virtual
|
|
||||||
* sub-tree.
|
|
||||||
*/
|
|
||||||
public static class VirtualSubtreeRootView extends View {
|
|
||||||
|
|
||||||
/** Paint object for drawing the virtual sub-tree */
|
|
||||||
private final Paint mPaint = new Paint();
|
|
||||||
|
|
||||||
/** Temporary rectangle to minimize object creation. */
|
|
||||||
private final Rect mTempRect = new Rect();
|
|
||||||
|
|
||||||
/** Handle to the system accessibility service. */
|
|
||||||
private final AccessibilityManager mAccessibilityManager;
|
|
||||||
|
|
||||||
/** The virtual children of this View. */
|
|
||||||
private final List<VirtualView> mChildren = new ArrayList<VirtualView>();
|
|
||||||
|
|
||||||
/** The instance of the node provider for the virtual tree - lazily instantiated. */
|
|
||||||
private AccessibilityNodeProvider mAccessibilityNodeProvider;
|
|
||||||
|
|
||||||
/** The last hovered child used for event dispatching. */
|
|
||||||
private VirtualView mLastHoveredChild;
|
|
||||||
|
|
||||||
public VirtualSubtreeRootView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
|
|
||||||
Service.ACCESSIBILITY_SERVICE);
|
|
||||||
createVirtualChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
|
|
||||||
// Instantiate the provide only when requested. Since the system
|
|
||||||
// will call this method multiple times it is a good practice to
|
|
||||||
// cache the provider instance.
|
|
||||||
if (mAccessibilityNodeProvider == null) {
|
|
||||||
mAccessibilityNodeProvider = new VirtualDescendantsProvider();
|
|
||||||
}
|
|
||||||
return mAccessibilityNodeProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
|
||||||
// This implementation assumes that the virtual children
|
|
||||||
// cannot overlap and are always visible. Do NOT use this
|
|
||||||
// code as a reference of how to implement hover event
|
|
||||||
// dispatch. Instead, refer to ViewGroup#dispatchHoverEvent.
|
|
||||||
boolean handled = false;
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
Rect childBounds = child.mBounds;
|
|
||||||
final int childCoordsX = (int) event.getX() + getScrollX();
|
|
||||||
final int childCoordsY = (int) event.getY() + getScrollY();
|
|
||||||
if (!childBounds.contains(childCoordsX, childCoordsY)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final int action = event.getAction();
|
|
||||||
switch (action) {
|
|
||||||
case MotionEvent.ACTION_HOVER_ENTER: {
|
|
||||||
mLastHoveredChild = child;
|
|
||||||
handled |= onHoverVirtualView(child, event);
|
|
||||||
event.setAction(action);
|
|
||||||
} break;
|
|
||||||
case MotionEvent.ACTION_HOVER_MOVE: {
|
|
||||||
if (child == mLastHoveredChild) {
|
|
||||||
handled |= onHoverVirtualView(child, event);
|
|
||||||
event.setAction(action);
|
|
||||||
} else {
|
|
||||||
MotionEvent eventNoHistory = event.getHistorySize() > 0
|
|
||||||
? MotionEvent.obtainNoHistory(event) : event;
|
|
||||||
eventNoHistory.setAction(MotionEvent.ACTION_HOVER_EXIT);
|
|
||||||
onHoverVirtualView(mLastHoveredChild, eventNoHistory);
|
|
||||||
eventNoHistory.setAction(MotionEvent.ACTION_HOVER_ENTER);
|
|
||||||
onHoverVirtualView(child, eventNoHistory);
|
|
||||||
mLastHoveredChild = child;
|
|
||||||
eventNoHistory.setAction(MotionEvent.ACTION_HOVER_MOVE);
|
|
||||||
handled |= onHoverVirtualView(child, eventNoHistory);
|
|
||||||
if (eventNoHistory != event) {
|
|
||||||
eventNoHistory.recycle();
|
|
||||||
} else {
|
|
||||||
event.setAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case MotionEvent.ACTION_HOVER_EXIT: {
|
|
||||||
mLastHoveredChild = null;
|
|
||||||
handled |= onHoverVirtualView(child, event);
|
|
||||||
event.setAction(action);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!handled) {
|
|
||||||
handled |= onHoverEvent(event);
|
|
||||||
}
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
||||||
// The virtual children are ordered horizontally next to
|
|
||||||
// each other and take the entire space of this View.
|
|
||||||
int offsetX = 0;
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
Rect childBounds = child.mBounds;
|
|
||||||
childBounds.set(offsetX, 0, offsetX + childBounds.width(), childBounds.height());
|
|
||||||
offsetX += childBounds.width();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
// The virtual children are ordered horizontally next to
|
|
||||||
// each other and take the entire space of this View.
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
width += child.mBounds.width();
|
|
||||||
height = Math.max(height, child.mBounds.height());
|
|
||||||
}
|
|
||||||
setMeasuredDimension(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
// Draw the virtual children with the reusable Paint object
|
|
||||||
// and with the bounds and color which are child specific.
|
|
||||||
Rect drawingRect = mTempRect;
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
drawingRect.set(child.mBounds);
|
|
||||||
mPaint.setColor(child.mColor);
|
|
||||||
mPaint.setAlpha(child.mAlpha);
|
|
||||||
canvas.drawRect(drawingRect, mPaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the virtual children of this View.
|
|
||||||
*/
|
|
||||||
private void createVirtualChildren() {
|
|
||||||
// The virtual portion of the tree is one level deep. Note
|
|
||||||
// that implementations can use any way of representing and
|
|
||||||
// drawing virtual view.
|
|
||||||
VirtualView firstChild = new VirtualView(0, new Rect(0, 0, 150, 150), Color.RED,
|
|
||||||
"Virtual view 1");
|
|
||||||
mChildren.add(firstChild);
|
|
||||||
VirtualView secondChild = new VirtualView(1, new Rect(0, 0, 150, 150), Color.GREEN,
|
|
||||||
"Virtual view 2");
|
|
||||||
mChildren.add(secondChild);
|
|
||||||
VirtualView thirdChild = new VirtualView(2, new Rect(0, 0, 150, 150), Color.BLUE,
|
|
||||||
"Virtual view 3");
|
|
||||||
mChildren.add(thirdChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the selected state of a virtual view.
|
|
||||||
*
|
|
||||||
* @param virtualView The virtual view whose selected state to set.
|
|
||||||
* @param selected Whether the virtual view is selected.
|
|
||||||
*/
|
|
||||||
private void setVirtualViewSelected(VirtualView virtualView, boolean selected) {
|
|
||||||
virtualView.mAlpha = selected ? VirtualView.ALPHA_SELECTED : VirtualView.ALPHA_NOT_SELECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a hover over a virtual view.
|
|
||||||
*
|
|
||||||
* @param virtualView The virtual view over which is hovered.
|
|
||||||
* @param event The event to dispatch.
|
|
||||||
* @return Whether the event was handled.
|
|
||||||
*/
|
|
||||||
private boolean onHoverVirtualView(VirtualView virtualView, MotionEvent event) {
|
|
||||||
// The implementation of hover event dispatch can be implemented
|
|
||||||
// in any way that is found suitable. However, each virtual View
|
|
||||||
// should fire a corresponding accessibility event whose source
|
|
||||||
// is that virtual view. Accessibility services get the event source
|
|
||||||
// as the entry point of the APIs for querying the window content.
|
|
||||||
final int action = event.getAction();
|
|
||||||
switch (action) {
|
|
||||||
case MotionEvent.ACTION_HOVER_ENTER: {
|
|
||||||
sendAccessibilityEventForVirtualView(virtualView,
|
|
||||||
AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
|
|
||||||
} break;
|
|
||||||
case MotionEvent.ACTION_HOVER_EXIT: {
|
|
||||||
sendAccessibilityEventForVirtualView(virtualView,
|
|
||||||
AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a properly initialized accessibility event for a virtual view..
|
|
||||||
*
|
|
||||||
* @param virtualView The virtual view.
|
|
||||||
* @param eventType The type of the event to send.
|
|
||||||
*/
|
|
||||||
private void sendAccessibilityEventForVirtualView(VirtualView virtualView, int eventType) {
|
|
||||||
// If touch exploration, i.e. the user gets feedback while touching
|
|
||||||
// the screen, is enabled we fire accessibility events.
|
|
||||||
if (mAccessibilityManager.isTouchExplorationEnabled()) {
|
|
||||||
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
|
||||||
event.setPackageName(getContext().getPackageName());
|
|
||||||
event.setClassName(virtualView.getClass().getName());
|
|
||||||
event.setSource(VirtualSubtreeRootView.this, virtualView.mId);
|
|
||||||
event.getText().add(virtualView.mText);
|
|
||||||
getParent().requestSendAccessibilityEvent(VirtualSubtreeRootView.this, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a virtual view given its id.
|
|
||||||
*
|
|
||||||
* @param id The virtual view id.
|
|
||||||
* @return The found virtual view.
|
|
||||||
*/
|
|
||||||
private VirtualView findVirtualViewById(int id) {
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
if (child.mId == id) {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a virtual View.
|
|
||||||
*/
|
|
||||||
private class VirtualView {
|
|
||||||
public static final int ALPHA_SELECTED = 255;
|
|
||||||
public static final int ALPHA_NOT_SELECTED = 127;
|
|
||||||
|
|
||||||
public final int mId;
|
|
||||||
public final int mColor;
|
|
||||||
public final Rect mBounds;
|
|
||||||
public final String mText;
|
|
||||||
public int mAlpha;
|
|
||||||
|
|
||||||
public VirtualView(int id, Rect bounds, int color, String text) {
|
|
||||||
mId = id;
|
|
||||||
mColor = color;
|
|
||||||
mBounds = bounds;
|
|
||||||
mText = text;
|
|
||||||
mAlpha = ALPHA_NOT_SELECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the provider that exposes the virtual View tree to accessibility
|
|
||||||
* services. From the perspective of an accessibility service the
|
|
||||||
* {@link AccessibilityNodeInfo}s it receives while exploring the sub-tree
|
|
||||||
* rooted at this View will be the same as the ones it received while
|
|
||||||
* exploring a View containing a sub-tree composed of real Views.
|
|
||||||
*/
|
|
||||||
private class VirtualDescendantsProvider extends AccessibilityNodeProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
|
|
||||||
AccessibilityNodeInfo info = null;
|
|
||||||
if (virtualViewId == View.NO_ID) {
|
|
||||||
// We are requested to create an AccessibilityNodeInfo describing
|
|
||||||
// this View, i.e. the root of the virtual sub-tree. Note that the
|
|
||||||
// host View has an AccessibilityNodeProvider which means that this
|
|
||||||
// provider is responsible for creating the node info for that root.
|
|
||||||
info = AccessibilityNodeInfo.obtain(VirtualSubtreeRootView.this);
|
|
||||||
onInitializeAccessibilityNodeInfo(info);
|
|
||||||
// Add the virtual children of the root View.
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
info.addChild(VirtualSubtreeRootView.this, child.mId);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Find the view that corresponds to the given id.
|
|
||||||
VirtualView virtualView = findVirtualViewById(virtualViewId);
|
|
||||||
if (virtualView == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Obtain and initialize an AccessibilityNodeInfo with
|
|
||||||
// information about the virtual view.
|
|
||||||
info = AccessibilityNodeInfo.obtain();
|
|
||||||
info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
|
|
||||||
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
|
|
||||||
info.setPackageName(getContext().getPackageName());
|
|
||||||
info.setClassName(virtualView.getClass().getName());
|
|
||||||
info.setSource(VirtualSubtreeRootView.this, virtualViewId);
|
|
||||||
info.setBoundsInParent(virtualView.mBounds);
|
|
||||||
info.setParent(VirtualSubtreeRootView.this);
|
|
||||||
info.setText(virtualView.mText);
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String searched,
|
|
||||||
int virtualViewId) {
|
|
||||||
if (TextUtils.isEmpty(searched)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
String searchedLowerCase = searched.toLowerCase();
|
|
||||||
List<AccessibilityNodeInfo> result = null;
|
|
||||||
if (virtualViewId == View.NO_ID) {
|
|
||||||
// If the search is from the root, i.e. this View, go over the virtual
|
|
||||||
// children and look for ones that contain the searched string since
|
|
||||||
// this View does not contain text itself.
|
|
||||||
List<VirtualView> children = mChildren;
|
|
||||||
final int childCount = children.size();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
VirtualView child = children.get(i);
|
|
||||||
String textToLowerCase = child.mText.toLowerCase();
|
|
||||||
if (textToLowerCase.contains(searchedLowerCase)) {
|
|
||||||
if (result == null) {
|
|
||||||
result = new ArrayList<AccessibilityNodeInfo>();
|
|
||||||
}
|
|
||||||
result.add(createAccessibilityNodeInfo(child.mId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the search is from a virtual view, find the view. Since the tree
|
|
||||||
// is one level deep we add a node info for the child to the result if
|
|
||||||
// the child contains the searched text.
|
|
||||||
VirtualView virtualView = findVirtualViewById(virtualViewId);
|
|
||||||
if (virtualView != null) {
|
|
||||||
String textToLowerCase = virtualView.mText.toLowerCase();
|
|
||||||
if (textToLowerCase.contains(searchedLowerCase)) {
|
|
||||||
result = new ArrayList<AccessibilityNodeInfo>();
|
|
||||||
result.add(createAccessibilityNodeInfo(virtualViewId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
|
||||||
if (virtualViewId == View.NO_ID) {
|
|
||||||
// Perform the action on the host View.
|
|
||||||
switch (action) {
|
|
||||||
case AccessibilityNodeInfo.ACTION_SELECT:
|
|
||||||
if (!isSelected()) {
|
|
||||||
setSelected(true);
|
|
||||||
return isSelected();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION:
|
|
||||||
if (isSelected()) {
|
|
||||||
setSelected(false);
|
|
||||||
return !isSelected();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Find the view that corresponds to the given id.
|
|
||||||
VirtualView child = findVirtualViewById(virtualViewId);
|
|
||||||
if (child == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Perform the action on a virtual view.
|
|
||||||
switch (action) {
|
|
||||||
case AccessibilityNodeInfo.ACTION_SELECT:
|
|
||||||
setVirtualViewSelected(child, true);
|
|
||||||
invalidate();
|
|
||||||
return true;
|
|
||||||
case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION:
|
|
||||||
setVirtualViewSelected(child, false);
|
|
||||||
invalidate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,12 +21,6 @@
|
|||||||
xml files, and adding additional information to AccessibilityEvents using
|
xml files, and adding additional information to AccessibilityEvents using
|
||||||
AccessibilityRecords.
|
AccessibilityRecords.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a href="AccessibilityNodeProviderActivity.html">Accessibility Node Provider</a></dt>
|
|
||||||
<dd>Demonstrates how to develop an accessibility node provider which manages a virtual
|
|
||||||
View tree reported to accessibility services. The virtual subtree is rooted at a View
|
|
||||||
that draws complex content and reports itself as a tree of virtual views, thus conveying
|
|
||||||
its logical structure.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
|||||||
Reference in New Issue
Block a user