Android progressBar не обновляет обзор прогресса/извлекаемый

два бара, которые показывают ход игры. Если пользователь получает очки или время и т.д., Необходимо обновить progressBars:

private TextView tv;
private ProgressBar levelHoldBar;
private ProgressBar levelUpBar;

//...
private void updateViews() {

    // ...
    levelHoldBar.setMax(currentLevel.getThreshold());
    levelHoldBar.setProgress(currentPoints > currentLevel.getThreshold() ? currentLevel.getThreshold() : currentPoints);

    levelUpBar.setMax(nextLevel.getThreshold());
    levelUpBar.setProgress(currentPoints > nextLevel.getThreshold() ? nextLevel.getThreshold() : currentPoints);

    tv.setText(currentPoints+"/"+currentLevel.getThreshold());

    Log.d(TAG, "hold prog/max "+levelHoldBar.getProgress()+"/"+levelHoldBar.getMax());
    Log.d(TAG, "up   prog/max "+levelUpBar.getProgress()+"/"+levelUpBar.getMax());
}

т. Выходы:

12-03 17:48:33.918: DEBUG/MainActivity(6829): hold prog/max 20/20
12-03 17:48:33.918: DEBUG/MainActivity(6829): up   prog/max 20/50

В конце файла Log.d(...) отображается ВСЕГДА правильные значения, но SOMETIMES визуальные бары progressBars не показывают правильные прогесты. Они показывают прогресс, который был установлен ранее, даже если геттеры для "max" и "progress" возвращают правильные значения (в примере на панели отображается около 20% (вместо 100%) для уровня HoldBar и около 2% (вместо 40 %) для уровня Up-bar). Я не могу понять, почему лог-вывод правильный, но чертежи ошибочны!? TextView (tv) обновлен правильно! Что тут происходит? Как я могу это исправить?

Ответ 1

РЕШЕНИЕ: это ошибка в ProgressBar!

наконец... Я думаю, что нашел решение...

это не работает, как можно было бы ожидать:

bar.setMax(50);
bar.setProgress(20);
bar.setMax(20);
bar.setProgress(20);

Функция setProgress (...), похоже, не вызывает обновление на drawable, если одно и то же значение передается снова. Но это не срабатывало и во время setMax. Поэтому обновление отсутствует. Кажется, что ошибка в android ProgressBar! Это заняло у меня около 8 часов. Lol: D

Чтобы решить эту проблему, я просто делаю bar.setProgress(0) перед каждым обновлением... это всего лишь обходной путь, но он работает для меня, как и ожидалось:

bar.setMax(50);
bar.setProgress(20);
bar.setProgress(0); // <--
bar.setMax(20);
bar.setProgress(20);

Ответ 2

Мне удалось заставить это работать с View.post():

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // ...

    mSeekBar.post(new Runnable() {
        @Override
        public void run() {
            mSeekBar.setProgress(percentOfFullVolume);
        }
    });
}

Как и ответы SKT, мне непонятно, почему это должно работать, если это не работает

mSeekBar.setProgress(percentOfFullVolume);

Однако, похоже, это правда и в том числе Android Lollipop.

Ответ 3

Вы можете использовать обработчик для обновления progressbar

Handler progressBarHandler = new Handler();

ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);;

progressBarHandler .post(new Runnable() {

      public void run() {
          bar.setProgress(progress);
      }
});

Ответ 4

Для меня по какой-то причине работал вызов setMax() до setProgress().

Ответ 5

В моем случае я создаю VerticalSeekBar, и решение Stuck не работает. Через несколько часов я нашел решение:

@Override
public synchronized void setProgress(int progress) {
    super.setProgress(progress);
    onSizeChanged(getWidth(), getHeight(), 0, 0);
}

Надеюсь, что кто-нибудь поможет.

Ответ 6

Создать updateThumb(); метод в VerticalSeekbar

public void updateThumb(){
     onSizeChanged(getWidth(), getHeight(), 0, 0);
}

И затем вызовите метод update thumb после установки прогресса.

seekBar.setProgress((int) progress);
seekBar.updateThumb();

его работа для меня в verticalseekbar calss

Ответ 7

Убедитесь, что для стиля progressBar установлено значение style = "@android: style/Widget.ProgressBar.Horizontal", в противном случае будет отображаться Indeterminate Progress.

(На всякий случай это кому-нибудь поможет)

Ответ 8

Спасибо. Застрял за сообщение о том, что есть ошибка Android. У меня также есть вертикальная панель поиска.

Проблема заключалась в том, когда я менял ход выполнения. Выбираемый будет обновлен, но панель будет установлена ​​в 0 и будет очень маленьким. Мне удалось изменить его с помощью updateThumb(), но прогресс все еще был равен 0.

Чтобы установить прогресс в исходное значение, я добавил mylayer.setLevel(...);. Я нашел это, прочитав исходный код ProgressBar.doRefreshProgress(...). Вы могли бы сделать seekBar.getProgressDrawable.setLevel(...).

LayerDrawable mylayer = //new LayerDrawable()
seekBar.setProgressDrawable(mylayer);
seekBar.updateThumb();
seekBar.setProgress((int) chLevel);
mylayer.setLevel((int) (chLevel / MAX_LEVEL * 10000));

Ответ 9

Я перепробовал все перечисленные решения, они не работали. Оказывается... реальная проблема заключалась в том, что мой код был занят выполнением, по существу блокируя поток пользовательского интерфейса. Поэтому правильное решение, которое немедленно решило проблему, заключалось в том, чтобы... поместить мой занятый код в асинхронную задачу.

В моем случае я загружал несколько тысяч записей из XML в базу данных SQLite. Естественно я хотел обновить индикатор выполнения. Код, который должен был это сделать (prg_bar.setProgress(iProgressPercentage)), ничего не сделал, и в конце загрузки пользовательский интерфейс, наконец, получил шанс на запуск. Poof, индикатор выполнения идет от нуля до 100.

Тот же код, помещенный в onProgressUpdate() асинхронной задачи, обернутый вокруг того же функционального кода, работал отлично. Это заставляет меня скептически отнестись к идее "что есть ошибка в штрих-коде прогресса" и что установка максимума и нуля или любой из этих вещей была чем-то большим, чем случайное обходное решение.

Ответ 10

Я пытался разными способами, вызывая setProgress в Thread, runOnUiThread, Handler, Runnable. Все они не работают.

Итак, наконец, установите значение dialog.setIndeterminate(false); буду работать.

После того, как вы установили dialog.setIndeterminate(true); прогресс не будет обновляться вообще.

public static ProgressDialog createProgressDialog(Activity activity, int messageID, boolean cancelable) {
    ProgressDialog dialog = new ProgressDialog(activity, R.style.DialogButtonTint);
    dialog.setMessage(activity.getString(messageID));
    dialog.setIndeterminate(false);
    dialog.setMax(100);
    dialog.setSecondaryProgress(0);
    dialog.setProgress(0);
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    dialog.setCancelable(cancelable);
    dialog.show();
    return dialog;
}

Ответ 11

Это сработало для меня...

OneFragmen.java

public class OneFragment extends Fragment{

public OneFragment() {
    // Required empty public constructor
}
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;

int progress=0;
private Handler handler = new Handler();
TextView txtProgress;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(
    LayoutInflater inflater, 
    ViewGroup container,
    Bundle savedInstanceState ) {

   View view =  inflater.inflate(R.layout.fragment_one, container, false);
    getActivity().setTitle(R.string.app_name);

   final ProgressBar spinner = 
       (ProgressBar) view.findViewById(R.id.outerProgressBar);
    Resources res = getResources();
    Drawable drawable = res.getDrawable(R.drawable.circular);
    txtProgress = (TextView)view.findViewById(R.id.txtProgress);
    spinner.setProgressDrawable(drawable);
    spinner.setSecondaryProgress(100);
    spinner.setMax(100);
    spinner.setProgress(0);

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (progress < 100) {
                progress += 1;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        spinner.setProgress(progress);
                        txtProgress.setText(progress + "%");
                    }
                });
                try {
                    Thread.sleep(28);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
    return view;
  }
}

Ответ 12

Ничто здесь не работало для меня, поэтому я пришел с немного другим решением. Я заметил, что все работает хорошо, пока я не попытаюсь изменить максимальное значение (вызывая setMax с другим значением).

Мой код:

class FixedSeekBar : SeekBar {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    companion object {
        private const val PROGRESS_MAX = 1000000.toDouble()
    }

    private var mLastMaxValue: Int = 100

    override fun setMax(max: Int) {
        mLastMaxValue = max
        super.setMax(PROGRESS_MAX.toInt())
    }

    fun setProgressFixed(progress: Int) {
        setProgress((PROGRESS_MAX / mLastMaxValue * progress).toInt())
    }

    fun getProgressFixed(): Int {
        return (getProgress() / PROGRESS_MAX * mLastMaxValue).toInt()
    }

}

Это отлично работает для меня. Я могу назвать setMax как обычно, и мне просто нужно заменить getProgress и setProgress с помощью getProgressFixed и setProgressFixed.

Не переопределяйте setProgress и getProgress. Они называются внутренне.

Мое решение не учитывается с помощью setMin. Если вам это нужно, измените код соответствующим образом.

Ответ 13

если вы любите полный прогрессбар

time_prg_bar.setMax(100);
time_prg_bar.setProgress(0); <--

если ваш прогрессбар пуст

time_prg_bar.setMax(100);
time_prg_bar.setProgress(100); <--

Ответ 14

каждый. в случае существующего прогресса и нового значения прогресса, индикатор выполнения не обновляется. таким образом, вы устанавливаете новое значение как близкое значение, это простой способ.

@Override
public synchronized void setProgress(int progress)
{
    if (getProgress() == progress)
    {
        if (progress > 0)   progress -= 1;
        else                progress += 1;
    }

    super.setProgress(progress);
}

Ответ 15

У меня сработало, если я установил setVisibility() на видимый перед каждым setProgress()

setVisibility(View.VISIBLE);
setProgress(progress);