我尝试在名为MyCompass的自定义视图上启用辅助功能。指南针有两个值,风速和风向,如果启用了TalkBack和Explore By Touch,我希望当用户触摸指南针时大声读出它们。正如您在下面的代码中看到的,我将几个日志语句用于调试目的。我确实得到两者的输出如下。
D/MyCompass: accessibility event sent D/MyCompass: populate with 0.36666667, 267.0
但是当我触摸MyCompass时,除了我在XML文件中的contentDescription中指定的内容之外,什么都不会被读出。 " @ string / compass"的值是"风速和风向",我的目标是在这些单词之后添加风速和风向的实际值。
<com.example.android.sunshine.app.MyCompass
android:focusable="true"
android:contentDescription="@string/compass"
android:layout_gravity="center_horizontal"
android:id="@+id/detail_wind_direction_compass"
android:layout_marginTop="4dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>;
这是代码。谢谢你的帮助。
package com.example.android.sunshine.app;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
public class MyCompass extends View {
private static final String LOG_TAG = MyCompass.class.getSimpleName();
private static final int COMPASS_WIDTH = 400;
private static final int COMPASS_HEIGHT = 400;
private static final int MAX_HAND_LENGTH = 200;
private static final int HAND_WIDTH = 10;
private static final int COMPASS_RADIUS = MAX_HAND_LENGTH / 2;
private static final float HAND_MAX_M_PER_SEC = 10;
private static final float WIND_SPEED_GREEN = 4;
private static final float WIND_SPEED_YELLOW = 6;
private static final float WIND_SPEED_RED = 8;
private static final int GREEN = 0xff00ff00;
private static final int BLUE = 0xff0000ff;
private static final int YELLOW = 0xffffff00;
private static final int RED = 0xffff0000;
private static final Paint BLUE_PAINT = new Paint();
private static final Paint GREEN_PAINT = new Paint();
private static final Paint YELLOW_PAINT = new Paint();
private static final Paint RED_PAINT = new Paint();
private ShapeDrawable mGreenCircle;
private ShapeDrawable mYellowCircle;
private ShapeDrawable mRedCircle;
private float mDirection = 0;
private float mSpeed = 0;
private int centerX = COMPASS_WIDTH / 2;
private int centerY = COMPASS_HEIGHT / 2;
// for code
public MyCompass(Context context) {
super(context);
}
// for XML file
public MyCompass(Context context, AttributeSet attrs) {
super(context, attrs);
BLUE_PAINT.setColor(BLUE);
BLUE_PAINT.setStyle(Paint.Style.STROKE);
BLUE_PAINT.setStrokeWidth(HAND_WIDTH);
GREEN_PAINT.setColor(GREEN);
YELLOW_PAINT.setColor(YELLOW);
RED_PAINT.setColor(RED);
mGreenCircle = new ShapeDrawable(new OvalShape());
mYellowCircle = new ShapeDrawable(new OvalShape());
mRedCircle = new ShapeDrawable(new OvalShape());
drawCircle(mGreenCircle, Math.round(MAX_HAND_LENGTH / HAND_MAX_M_PER_SEC * WIND_SPEED_GREEN), GREEN);
drawCircle(mYellowCircle, Math.round(MAX_HAND_LENGTH / HAND_MAX_M_PER_SEC * WIND_SPEED_YELLOW), YELLOW);
drawCircle(mRedCircle, Math.round(MAX_HAND_LENGTH / HAND_MAX_M_PER_SEC * WIND_SPEED_RED), RED);
}
private void drawCircle(ShapeDrawable drawable, int radius, int color) {
drawable.getPaint().setColor(color);
drawable.setBounds(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
}
// for inflation
public MyCompass(Context context, AttributeSet attrs, int defaultStyle) {
super(context, attrs, defaultStyle);
}
// speed is in km/h
public void setDirectionAndSpeed(float direction, float speed) {
mDirection = direction;
mSpeed = speed * 1000 / 3600; // convert km/h to m/s
MyCompass compass = (MyCompass) findViewById(R.id.detail_wind_direction_compass);
//compass.setContentDescription(compass.getContentDescription() + " is " + mSpeed + " m/s at " + mDirection);
Context context = getContext();
AccessibilityManager accessibilityManager =
(AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);
if (accessibilityManager.isEnabled()) {
sendAccessibilityEvent(
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
Log.d(LOG_TAG, "accessibility event sent");
}
invalidate();
}
@Override
protected void onMeasure(int wMeasureSpec, int hMeasureSpec) {
int wSpecMode = MeasureSpec.getMode(wMeasureSpec);
int wSpecSize = MeasureSpec.getSize(wMeasureSpec);
int myWidth = wSpecSize;
int hSpecMode = MeasureSpec.getMode(hMeasureSpec);
int hSpecSize = MeasureSpec.getSize(hMeasureSpec);
int myHeight = hSpecSize;
if (wSpecMode == MeasureSpec.EXACTLY) {
myWidth = wSpecSize;
} else if (wSpecMode == MeasureSpec.AT_MOST || wSpecMode == MeasureSpec.UNSPECIFIED) {
// Wrap Content
myWidth = COMPASS_WIDTH;
}
if (hSpecMode == MeasureSpec.EXACTLY) {
myHeight = hSpecSize;
} else if (hSpecMode == MeasureSpec.AT_MOST || hSpecMode == MeasureSpec.UNSPECIFIED) {
// Wrap Content
myHeight = COMPASS_HEIGHT;
}
setMeasuredDimension(myWidth, myHeight);
}
@Override
protected void onDraw(Canvas canvas) {
mRedCircle.draw(canvas);
mYellowCircle.draw(canvas);
mGreenCircle.draw(canvas);
int handLength = (int) (mSpeed / HAND_MAX_M_PER_SEC * MAX_HAND_LENGTH);
canvas.drawLine(
centerX,
centerY,
(float) (centerX + handLength * Math.sin(mDirection / 180 * Math.PI)),
(float) (centerY - handLength * Math.cos(mDirection / 180 * Math.PI)),
BLUE_PAINT
);
}
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent ev) {
super.dispatchPopulateAccessibilityEvent(ev);
if (ev.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
Log.d(LOG_TAG, "populate with " + mSpeed + ", " + mDirection);
ev.getText().add(String.valueOf(mSpeed) + " m/s from " + String.valueOf(mDirection));
}
return true;
}
}
答案 0 :(得分:1)
您的问题很可能正在发生,因为您的自定义视图默认情况下无法关注,这是TalkBack的要求。您可以通过将属性android:focusable
设置为true来解决此问题,如下所示:
<com.example.android.sunshine.app.MyCompass
android:layout_gravity="center_horizontal"
android:id="@+id/detail_wind_direction_compass"
android:layout_marginTop="4dp"
android:focusable="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
中有关它的更多信息
答案 1 :(得分:1)
我终于找到了答案。为了使TalkBack在dispatchPopulateAccessibilityEvent()中读出动态添加的文本,我需要发送AccessibilityEvent.TYPE_VIEW_FOCUSED事件而不是AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED事件。
答案 2 :(得分:0)
简单地实施辅助功能事件,不会让Android大声读出。可访问性事件监视用户在辅助功能模式下如何与其设备进行交互。如果您希望以这种方式读出某些内容,则必须实现TextToSpeech。