Android SeekBar 对讲,话太多了

Android SeekBar talkback, talking too much

(Android) 在音乐播放器上,您按预期更新搜索栏:

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()));
                    ...

但是,如果焦点在搜索栏上,则对讲会稳定且不间断地反馈进度。喜欢 "seek control 25%"、"seek control 25%"、"seek control 25%"、"seek control 26%"、"seek control 26%"、"seek control 27%"

我缺少某事但无法解决问题。我已将 contentDescription 设置为 @null 以外的值。但是这次它没有停止读取内容描述。

在 Spotify 客户端上,我检查了一次,它读取的进度为 "xx percent"。尽管将焦点保存在搜索栏上。

当我将精度编辑为 1 或 100 时,搜索栏上的精度就会丢失。歌曲中好像有几个片段。您可以通过在搜索栏上滑动来播放一个或另一个。

有人遇到过这样的事情吗?我在 google 文档、堆栈网络或其他地方找不到任何内容。

我遇到了问题,发现 SeekBar 在每次更新时读取百分比。

这很有帮助,我仅在百分比发生变化时更新 SeekBar 但仍保持高精度(在我的例子中以毫秒为单位)。

@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初始化为-1。

请注意,此解决方案与 Spotify 的解决方案不同。
选择 SeekBar 时,Spotify 会覆盖系统通告的消息。
这有以下 2 个效果:

  • 可以根据需要随时进行更新,而无需重复百分比
  • 如果在选择 SeekBar 时百分比发生变化,则不会通知任何内容

第 2 点可能是一个缺点,具体取决于您想要实现的目标。

您可以只重写 sendAccessibilityEvent(),这样它就会忽略描述更新:

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

正如 Altoyyr 所提到的,这具有忽略所有描述更新的副作用,包括使用音量按钮滚动。因此,您需要添加回发送音量按下操作的事件:

@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);
}