Android SeekBar talkback, talking too much

≯℡__Kan透↙ 提交于 2019-12-11 13:45:43

问题


(Android) On a music player, you update the seekbar as expected with this:

PRECISION_SEEKBAR = 100000;
((SeekBar) findViewById(R.id.seekBar2)).setMax(PRECISION_SEEKBAR);

timerSeekBarUpdate.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                final SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);

                @Override
                public void run() {
                    if (control == null || player == null) {
                        cancel();
                        return;
                    }
                    seekBar.setProgress((int) (player.getCurrentPosition() * PRECISION_SEEKBAR / player.getDuration()));
                    ...

However, if the focus is on the seek bar, talkback steadily and nonstop gives feedback for the progress. Like "seek control 25%", "seek control 25%", "seek control 25%", "seek control 26%", "seek control 26%", "seek control 27%"

I'm missing sth but couldnot solve the problem. I have set the contentDescription to other than @null. But then it reads the content description this time without stopping.

On Spotify client, I checked, it reads the progress as "xx percent" just once. Despite saving the focus on the seekbar.

When I edit the precision for 1 or 100, then you lose the precision on the seekbar. It looks like there are a few parts in the song. You either play one or another by swiping on the seekbar.

Has anybody experienced sth like this? I couldn't find anything on google docs, stack network or somewhere else.


回答1:


I had the problem and found that SeekBar reads the percentage on every update.

It helped, that I update the SeekBar only when the percentage changes but still keep a high precision (in my case in ms).

@Override
public void updateSeekBar(final int currentPosInMillis, final int durationInMillis) {
    long progressPercent = calculatePercent(currentPosInMillis, durationInMillis);

    if (progressPercent != previousProgressPercent) {
        seekBar.setMax(durationInMillis);
        seekBar.setProgress(currentPosInMillis);
    }
    previousProgressPercent = progressPercent;
}

private int calculatePercent(int currentPosInMillis, int durationInMillis) {
    if(durationInMillis == 0) {
        return 0;
    }
    return (int) (((float)currentPosInMillis / durationInMillis) * 100);
} 

previousProgressPercent is initialized to -1.

Please note that this solution is not the same as Spotify does it.
Spotify overrides the message announced by the system when the SeekBar gets selected.
This has following 2 effects:

  • Updates can be made as often as you want without the percentage beeing repeated
  • When the percentage changes while the SeekBar is selected then nothing gets announced

Point 2 might me a drawback depending on what you want to achieve.




回答2:


You can just override sendAccessibilityEvent() so it ignores description updates:

@Override
public void sendAccessibilityEvent(int eventType) {
    if (eventType != AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION) {
        super.sendAccessibilityEvent(eventType);
    }
}

As Altoyyr mentioned, this has the side effect of ignore ALL description updates, including scrolling with volume buttons. So you'll need add back sending the event for volume press actions:

@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
    switch (action) {
        case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
        case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
            super.sendAccessibilityEvent(AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
        }
    }
    return super.performAccessibilityAction(action, arguments);
}


来源:https://stackoverflow.com/questions/36971528/android-seekbar-talkback-talking-too-much

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!