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