两个显示游戏进度的栏。如果用户获得积分或时间等,则应更新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的可视栏不显示正确的progesses。它们显示先前设定的进度,即使“最大”和“进度”的吸气剂返回正确的值(在示例中,条形图显示levelHoldBar约20%(而不是100%)和约2%(而不是40%) %)为levelUp-bar)。我无法弄清楚,为什么日志输出是正确的但是drawables是错误的!? TextView(tv)正确更新!这里发生了什么?我该如何解决这个问题?
答案 0 :(得分:42)
解决方案:这是ProgressBar中的Bug!
终于......我想我找到了解决方案......
这不像预期的那样有效:
bar.setMax(50);
bar.setProgress(20);
bar.setMax(20);
bar.setProgress(20);
如果再次传递相同的值,则setProgress(...)似乎不会触发drawable上的更新。但它也不会在setMax期间触发。因此缺少更新。看起来像android ProgressBar中的Bug!这花了我大约8个小时..大声笑:D
要解决这个问题,我只是在每次更新之前做一个bar.setProgress(0)...这只是一种解决方法,但它对我有用:
bar.setMax(50);
bar.setProgress(20);
bar.setProgress(0); // <--
bar.setMax(20);
bar.setProgress(20);
答案 1 :(得分:19)
我能够将其与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。
答案 2 :(得分:13)
您可以使用处理程序更新progressbar
Handler progressBarHandler = new Handler();
ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);;
progressBarHandler .post(new Runnable() {
public void run() {
bar.setProgress(progress);
}
});
答案 3 :(得分:9)
对我来说,在 setMax()
之前调用setProgress()
是出于某种原因。
答案 4 :(得分:7)
就我而言,我创建了VerticalSeekBar,而Stuck的解决方案不起作用。几小时后,我找到了解决方案:
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
希望能帮助任何人。
答案 5 :(得分:3)
创建updateThumb(); VerticalSeekbar中的方法
public void updateThumb(){
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
然后在设置进度后调用update thumb方法。
seekBar.setProgress((int) progress);
seekBar.updateThumb();
在verticalseekbar calss中为我工作
答案 6 :(得分:2)
确保将progressBar的样式设置为 风格=“@安卓风格/ Widget.ProgressBar.Horizontal” 否则它将显示Indeterminate Progress
(以防它会帮助某人)
答案 7 :(得分:2)
我通过以下方式尝试了很多方法:在 Thread , runOnUiThread , Handler,Runnable 中调用 setProgress 。它们都不起作用。
因此,最后,设置值 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;
}
答案 8 :(得分:1)
感谢Stuck的帖子说明有一个Android错误。我也有一个垂直搜索栏。
问题出在我改变进度的时候。 drawable将被更新,但条形将设置为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 :(得分:1)
我尝试了列出的所有解决方案,但它们均无效。事实证明……真正的问题是我的代码忙于运行,实际上阻塞了UI线程。因此,可以立即解决问题的正确解决方案是...将繁忙的代码放在异步任务中。
就我而言,我正在将数千条记录从XML加载到SQLite数据库中。自然,我想更新进度条。应该执行此操作的代码(prg_bar.setProgress(iProgressPercentage))没有任何作用,并且在加载结束时,UI终于有机会运行。 of,进度条从零到100。
将相同的代码放入异步任务的onProgressUpdate()中,并包装相同的功能代码,即可完美地工作。这使我对“进度条中存在错误”的想法表示怀疑,并且将max和max设置为零,或者其中的任何事情都不是偶然的解决方法。
答案 10 :(得分:0)
这对我有用......
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;
}
}
答案 11 :(得分:0)
这里没有什么对我有用,所以我找到了一个不同的解决方案。我注意到一切都运行良好,直到我尝试更改最大值(使用不同的值调用 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 ,我只需要用 getProgressFixed 和 setProgressFixed替换 getProgress 和 setProgress
请勿覆盖 setProgress 和 getProgress 。它们在内部被称为。
我的解决方案不计入 setMin 。如果需要,请相应地更改代码。
答案 12 :(得分:0)
如果你喜欢完整的进度条
time_prg_bar.setMax(100);
time_prg_bar.setProgress(0); <--
如果您的进度条为空
time_prg_bar.setMax(100);
time_prg_bar.setProgress(100); <--
答案 13 :(得分:0)
每个人。 如果存在进度并且新进度值相同, 进度栏未更新。 因此您可以将新值设置为接近值,这很容易。
@Override
public synchronized void setProgress(int progress)
{
if (getProgress() == progress)
{
if (progress > 0) progress -= 1;
else progress += 1;
}
super.setProgress(progress);
}
答案 14 :(得分:-1)
对于我来说,如果我在每个setProgress()之前将setVisibility()设置为可见,则对我来说工作
setVisibility(View.VISIBLE);
setProgress(progress);