如何设置使用 Canvas 绘制的圆圈的可访问性?

How to set accessibility to circles drawn using Canvas?

我有一个自定义视图,我在 Android 中使用 canvas 绘制了 6 个圆圈。这些圆圈充当页面指示器;这意味着在单击每个圆圈(使用 canvas 绘制)时,不同的项目将显示在视图寻呼机中。现在我的要求是为每个圈子设置单独的焦点并为每个圈子设置不同的可访问性。请帮忙。提前致谢。 谢谢, 拉凯什

您应该使用 View.getX() 和 View.getY() 获取视图的位置以获得左上角的 x 和 y 并假设您知道半径(或能够获得width/height 的视图来确定半径)。之后,得到:

xTouch = MotionEvent.getX();
yTouch = MotionEvent.getY();

然后检查条件如果:

     (xTouch - (x + radius)) * (xTouch - (x + radius)) + (yTouch - (y + radius)) * (yTouch - (y + radius)) <= radius * radius

该公式只是学校几何学的解释,用于确定点是否在圆区域内。详见笛卡尔坐标圆方程

值解释为:

(x+半径)和(y+半径)为圆心

(xTouch - (x + radius)) 是触摸点到中心X的距离。

(yTouch - (y + radius)) 是触摸点到Y中心的距离。

如果 TackBack 打开,每个圆圈的可访问性和要读出的可访问性文本,因此完整场景的代码是:

package com.example.hello_world;

import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity implements OnInitListener {
    String mText_To_Speach_text;
    private int MY_DATA_CHECK_CODE = 0;
    TextToSpeech myTTS;
    int initStatus = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));

        Intent checkTTSIntent = new Intent();
        checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
    }

    class MyView extends View {

        private Path mPath, mPath2, mPath3, mPath4, mPath5;
        private Paint mPaint;
        private RectF mOval, mOval2;
        Region mRegion1, mRegion2, mRegion3, mRegion4, mRegion5, mRegion6;

        public MyView(Context context) {
            super(context);
            mPath = new Path();
            mPath2 = new Path();
            mPath3 = new Path();
            mPath4 = new Path();
            mPath5 = new Path();
            mPaint = new Paint();
            mPaint.setColor(0xffff0000);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            mPath.reset();
            mPath.addCircle((w / 2) - 120, h / 2, 30, Direction.CW);
            mPath.close();

            mPath2.reset();
            mPath2.addCircle((w / 2) - 60, h / 2, 30, Direction.CW);
            mPath2.close();

            mPath3.reset();
            mPath3.addCircle(w / 2, h / 2, 30, Direction.CW);
            mPath3.close();

            mPath4.reset();
            mPath4.addCircle((w / 2) + 60, h / 2, 30, Direction.CW);
            mPath4.close();

            mPath5.reset();
            mPath5.addCircle((w / 2) + 120, h / 2, 30, Direction.CW);
            mPath5.close();

        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(0xffffffff);

            mPaint.setStyle(Style.FILL);
            canvas.drawPath(mPath, mPaint);
            canvas.drawPath(mPath2, mPaint);
            canvas.drawPath(mPath3, mPaint);
            canvas.drawPath(mPath4, mPaint);
            canvas.drawPath(mPath5, mPaint);

            RectF rectF1 = new RectF();
            mPath.computeBounds(rectF1, true);
            mRegion1 = new Region();
            mRegion1.setPath(mPath, new Region((int) rectF1.left,
                    (int) rectF1.top, (int) rectF1.right, (int) rectF1.bottom));

            RectF rectF2 = new RectF();
            mPath2.computeBounds(rectF2, true);
            mRegion2 = new Region();
            mRegion2.setPath(mPath2, new Region((int) rectF2.left,
                    (int) rectF2.top, (int) rectF2.right, (int) rectF2.bottom));

            RectF rectF3 = new RectF();
            mPath3.computeBounds(rectF3, true);
            mRegion3 = new Region();
            mRegion3.setPath(mPath3, new Region((int) rectF3.left,
                    (int) rectF3.top, (int) rectF3.right, (int) rectF3.bottom));

            RectF rectF4 = new RectF();
            mPath4.computeBounds(rectF4, true);
            mRegion4 = new Region();
            mRegion4.setPath(mPath4, new Region((int) rectF4.left,
                    (int) rectF4.top, (int) rectF4.right, (int) rectF4.bottom));

            RectF rectF5 = new RectF();
            mPath5.computeBounds(rectF5, true);
            mRegion5 = new Region();
            mRegion5.setPath(mPath5, new Region((int) rectF5.left,
                    (int) rectF5.top, (int) rectF5.right, (int) rectF5.bottom));

        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (mRegion1.contains(x, y)) {
                    mText_To_Speach_text = "Circle1";
                    speakWords(mText_To_Speach_text);
                } else if (mRegion2.contains(x, y)) {
                    mText_To_Speach_text = "Circle2";
                    speakWords(mText_To_Speach_text);
                } else if (mRegion3.contains(x, y)) {
                    mText_To_Speach_text = "Circle3";
                    speakWords(mText_To_Speach_text);
                } else if (mRegion4.contains(x, y)) {
                    mText_To_Speach_text = "Circle4";
                    speakWords(mText_To_Speach_text);
                } else if (mRegion5.contains(x, y)) {
                    mText_To_Speach_text = "Circle5";
                    speakWords(mText_To_Speach_text);
                }
            }
            return true;
        }
    }

    private void speakWords(String speech) {
        myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
    }

    @Override
    public void onInit(int status) {
        if (initStatus == TextToSpeech.SUCCESS) {
            if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE)
                myTTS.setLanguage(Locale.US);
        } else if (initStatus == TextToSpeech.ERROR) {
            Toast.makeText(this, "Sorry! Text To Speech failed...",
                    Toast.LENGTH_LONG).show();
        }

    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == MY_DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                myTTS = new TextToSpeech(this, this);
            } else {
                Intent installTTSIntent = new Intent();
                installTTSIntent
                        .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installTTSIntent);
            }
        }
    }

}

我不得不使用 ExploreByTouchHelper 来实现我的要求,正如评论中@alanv 和@pskink 所解释的那样。

https://youtu.be/ld7kZRpMGb8?t=1196

谢谢大家!