8

当我以编程方式设置 SeekBar 的进度时,我的 onProgressChanged() 事件不会被触发,但是当我以物理方式移动 SeekBar 滑块时它会被触发得非常好。

我希望在使用 setProgress() 时触发该事件 - Android 开发人员参考甚至指出:

public abstract void onProgressChanged (SeekBar seekBar, int progress, boolean fromUser)

进度级别已更改的通知。客户端可以使用 fromUser 参数来区分用户发起的更改和以编程方式发生的更改。

我的项目中的一些代码片段:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity);               

    final SeekBar mySeekBar = ((SeekBar) findViewById(R.id.mySeekBar));
    
    mySeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
        @Override
        public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
            // Do some stuff
        }
    }
}


@Override
protected void onResume() {
    super.onResume();

    final SeekBar mySeekBar = ((SeekBar) findViewById(R.id.mySeekBar));
    mySeekBar.setProgress(someValue); // This SHOULD trigger onProgressChanged(), but it doesn't...
}
4

10 回答 10

9

刚才偶然发现了同样的问题。

在我的情况下,onProgressChanged并没有仅仅因为值实际上没有改变而被解雇。我设置的值与当前值相同(0:)

(我看不出你的代码有什么问题)

于 2013-09-20T17:14:30.467 回答
6

+1 Romuald Brunet 的回答:

这是我修复它的“黑客”:

        <SeekBar android:id="@+id/seekbar" 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"  
            android:progress="1"
            android:max="200" />

注意 progress="1",将布局中的默认进度设置为 1,然后在我的代码中,当我实际将其默认为 0 时,进度发生变化并触发 onProgressChanged() 事件。

于 2013-10-12T15:09:55.903 回答
3

我的听众没有开火,因为我setProgress()在设置听众之前打电话

于 2019-03-22T07:45:26.573 回答
1

在xml文件中设置progress=10,如下图:

<SeekBar android:id="@+id/seekbar" 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content"  
  android:progress="10"
  android:max="100" />

然后在主文件中写入以下代码:

new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            seekbar.setProgress(50)
                        }
                    }, 100);

减少延迟,以免影响 UI。

于 2018-11-27T18:34:35.040 回答
1

您需要确保该值确实已更改,否则将不会被拾取。放入2行。第一个不想要。第二个愿望。

seekbar.setProgress(7); // Necessary to force the change to desired
seekbar.setProgress(50); // Desired progress
于 2020-03-25T18:10:22.397 回答
1

SeekBar.OnSeekBarChangeListener.onProgressChanged仅在实际更改进度时调用,不一定在调用时setProgress调用 - 只有当新进度与上一个不同时才会发生这种情况。

查看SeekBar 的源代码,它扩展了 AbsSeekBar ,而 AbsSeekBar又扩展了ProgressBar,我们可以看到除非新进度与前一个进度不同,否则调用setProgress()不会触发onProgressChanged()事件,如下面的源代码所示。

/* 
    Snippet from ProgressBar.java 
*/

public void setProgress(int progress, boolean animate) {
    setProgressInternal(progress, false, animate);
}


synchronized boolean setProgressInternal(int progress, boolean fromUser, boolean animate) {
    if (mIndeterminate) {
        // Not applicable.
        return false;
    }

    progress = MathUtils.constrain(progress, mMin, mMax);
    if (progress == mProgress) {
        // No change from current.
        return false;
    }

    mProgress = progress;
    refreshProgress(R.id.progress, mProgress, fromUser, animate);
    return true;
}
于 2017-11-01T14:06:39.473 回答
0

接受的答案对我不起作用,因为当进度以编程方式设置为 1 时它停止被触发(这是同一个错误)。

我所做的是自己调用 onProgressChanged() 。我的搜索栏是一个成员变量。

void setProgressValue(int progress){
    if(progress == 0){ //the default progress is 0. if i set it to 0 again the call back wont be invoked
        mSeekBar.setProgress(progress);
        onProgressChanged(progress,mSeekBar,false);
    }
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    //things to be done when the call back is received
}

发帖希望以后能帮到人。

于 2019-02-13T09:23:18.890 回答
0

一种可能的解决方法是创建自己的小部件扩展 Seekbar 并根据您的需要实现两种方法:

    private OnSeekBarChangeListener onSeekBarChangeListener;

    @Override
    public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
        super.setOnSeekBarChangeListener(l);
        onSeekBarChangeListener = l;
    }

    @Override
    public void setProgress(int progress) {
        super.setProgress(progress);
        if (onSeekBarChangeListener != null) {
            onSeekBarChangeListener.onProgressChanged(this, progress, false);
        }
    }
于 2018-11-27T20:33:12.110 回答
-1

我可以肯定地确认setProgress适用于 Android 版本 6.0.1。

另一个StackOverflow 答案 说这是一个错误。如果这是真的,那肯定不再是这样了。

此代码适用于我的测试设置:

@Override
public void onResume() {
    super.onResume();

    SeekBar seekBar = (SeekBar)findViewById(R.id.seek_bar);
    seekBar.setProgress(seekBar.getProgress());
}

正如预期的那样,SeekBar'sOnSeekBarChangeListener正在被调用。

对于故障排除,请确保您正确设置了侦听器setOnSeekBarChangeListener(),并确保您实现了接口功能。其他 SO 答案似乎表明您应该只setProgress()从 UI 线程调用。 这个答案显示了如何做到这一点。

于 2016-09-17T07:00:32.417 回答
-1

只需调用

 mySeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
    @Override
    public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
       int i=    arg0.getProgress();
     //youre seekbar.setProgress(i);
    }
}
于 2017-11-01T14:18:19.067 回答