Android: SeekBar onProgressChanged-событие не запускается при программной настройке прогресса

My onProgressChanged () - событие не запускается, когда я программно устанавливаю прогресс панели поиска, но он запускается отлично, когда я физически перемещаю ползунок панели поиска.

Я ожидал бы, что событие сработает при использовании setProgress () - ссылка разработчика Android даже заявляет, что:

публичный абстрактный 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...
}

5 ответов


+1 для ответа Ромуальда Брюне:

вот мой "хак", чтобы исправить это:

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

обратите внимание на прогресс= "1", Установите прогресс по умолчанию в макете на 1, затем в моем коде, когда я фактически по умолчанию его 0, происходит изменение прогресса и onprogresschanged() событие срабатывает.


наткнулся на ту же проблему только что.

в моем случае onProgressChanged не уволили просто потому, что значение фактически не изменилось. Я устанавливал то же значение, что и текущее (0 :)

(и я не вижу ничего плохого с вашим кодом)


Я могу с уверенностью подтвердить, что 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 ' s OnSeekBarChangeListener - это вызов.

для устранения неполадок, убедитесь, что вы правильно слушателя, используя setOnSeekBarChangeListener() и убедитесь, что вы реализуйте функции интерфейса. Другие ответы SO, похоже, указывают на то, что вы должны только позвонить setProgress() из потока пользовательского интерфейса. ответ показывает, как это можно сделать.


SeekBar.OnSeekBarChangeListener.onProgressChanged вызывается только тогда, когда прогресс фактически изменен, не обязательно, когда setProgress называется - это происходит только в том случае, если новый прогресс отличается от предыдущего.

смотрим источник SeekBar, которая расширяет 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;
}

просто позвоните

 mySeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
    @Override
    public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
       int i=    arg0.getProgress();
     //youre seekbar.setProgress(i);
    }
}