SeekBar颜色条与进度和拇指不匹配

时间:2013-01-19 13:24:34

标签: android seekbar repaint auto-rotation

当屏幕旋转时,我的搜索条的彩色条会回到初始值,而拇指则保持在正确的位置。

基本上是这样的:

enter image description here

它变成这样:

enter image description here

请注意,显示TextView的{​​{1}}已连接到搜索栏并正确显示相同的值,该值会在15中更新,并在搜索栏上使用onCreateView检索值,所以搜索栏在内部正确进行,但“忘记”更新其栏。另请注意,如果稍微移动,条形图将正确更新。

奇怪的是,我有一个相同的搜索栏,我在其上执行完全相同的操作(方法调用等),但这个问题从未出现过这个问题。

它们在XML布局文件中以相同的方式定义(getProgress除外)。

这些搜索栏位于显示为id的{​​{1}}内,这里或多或少是片段的代码:

Fragment

ViewPager是我创建的小部件,基本上是public class NewCharacterNameFragment extends Fragment implements NumericSeekBar.OnValueChangedListener { private static final String LEVEL = "org.my.package.LEVEL"; private static final String STATS = "org.my.package.STATS"; private NumericSeekBar levelBar; // Causing problems private NumericSeekBar statsBar; // Well behaved @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); if (savedInstanceState == null) { // defaults values to avoid multiple checks later savedInstanceState = new Bundle(); savedInstanceState.putInt(LEVEL, 1); savedInstanceState.putInt(STATS, 30); } View view = inflater.inflate(R.layout.new_character_name_fragment, container, false); levelBar = (NumericSeekBar) view.findViewById(R.id.levelSeekBar); statsBar = (NumericSeekBar) view.findViewById(R.id.statPointsSeekBar); levelBar.setValue(savedInstanceState.getInt(LEVEL)); levelBar.setMax(20); levelBar.setValueChangedListener(this); statsBar.setValue(savedInstanceState.getInt(STATS)); statsBar.setMax(100); statsBar.setValueChangedListener(this); // Initialize the text-views with the progress values: TextView tView = (TextView) view.findViewById(R.id.statPointsNumTextView); tView.setText(Integer.valueOf(statsBar.getValue()).toString()); tView = (TextView) view.findViewById(R.id.levelNumTextView); tView.setText(Integer.valueOf(levelBar.getValue()).toString()); return view; } @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); savedInstanceState.putInt(LEVEL, levelBar.getValue()); savedInstanceState.putInt(STATS, statsBar.getValue()); } @Override public void onNumericSeekBarValueChanged(NumericSeekBar bar, int value, boolean fromUser) { // Called whenever the seekbar value changes if (bar == statsBar) { TextView view = (TextView) getView().findViewById(R.id.statPointsNumTextView); view.setText(Integer.valueOf(value).toString()); } else if (bar == levelBar) { TextView view = (TextView) getView().findViewById(R.id.levelNumTextView); view.setText(Integer.valueOf(value).toString()); } } } ,带有两个递增和递减按钮以及搜索条:

NumericSeekBar

在仿真器和物理设备上都会发生这种情况。

编辑:我刚刚在Android 4模拟器上测试了我的应用程序,但这不会发生,所以它似乎与2.x有关。

EDIT2:我已尝试LinearLayout public class NumericSeekBar extends LinearLayout implements SeekBar.OnSeekBarChangeListener, View.OnClickListener { public interface OnValueChangedListener { public void onNumericSeekBarValueChanged(NumericSeekBar bar, int value, boolean fromUser); } private Button incButton; private Button decButton; private SeekBar seekBar; private OnValueChangedListener listener = null; private int maxValue = 100; private int value = 0; public NumericSeekBar(Context ctx) { super(ctx); setOpts(); setWidgets(); } public NumericSeekBar(Context ctx, AttributeSet attributes) { super(ctx, attributes); setOpts(); setWidgets(); } public void setValueChangedListener(OnValueChangedListener listener) { this.listener = listener; } public void setMax(int maxValue) { this.maxValue = maxValue; seekBar.setMax(maxValue); } public int getValue() { return this.value; // using seekBar.getProgress() obtains same results } public boolean setValue(int value) { if (value < 0 || value > maxValue) { return false; } this.value = value; seekBar.setProgress(value); return true; } @Override public void onStopTrackingTouch(SeekBar bar) { bar.setSecondaryProgress(bar.getProgress()); } @Override public void onStartTrackingTouch(SeekBar bar) { } @Override public void onProgressChanged(SeekBar bar, int value, boolean fromUser) { this.value = value; if (listener != null ){ listener.onNumericSeekBarValueChanged(this, value, fromUser); } if (!fromUser) { bar.setSecondaryProgress(0); } } @Override public void onClick(View v) { // Handle increment/decrement button clicks if (v.equals(incButton)) { this.setValue(this.getValue() + 1); } else if(v.equals(decButton)) { this.setValue(this.getValue() - 1); } } private void setOpts() { setOrientation(HORIZONTAL); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setShowDividers(SHOW_DIVIDER_NONE); } } private void setWidgets() { incButton = new Button(getContext()); decButton = new Button(getContext()); seekBar = new SeekBar(getContext()); incButton.setText("+"); incButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); incButton.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, (float) 0.4)); incButton.setOnClickListener(this); decButton.setText("-"); decButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); decButton.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, (float) 0.4)); decButton.setOnClickListener(this); LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, (float) 0.2); layoutParams.gravity = Gravity.CENTER; seekBar.setLayoutParams(layoutParams); setMax(this.maxValue); setValue(this.value); addView(incButton); addView(seekBar); addView(decButton); seekBar.setOnSeekBarChangeListener(this); } } invalidate()onCreateView中的条形码,但问题仍然存在。我还尝试在onStart中添加onResume,但没有任何改变。 我真的不明白发生了什么。

EDIT3:我添加了另一个包含其中六个条形的片段,上面代码中只有levelBar.setValue(levelBar.getValue())表现得很奇怪。我想知道这怎么可能。要么有一些非常奇怪的错误,要么我做的事情不正确,即使我看不到哪里(并且在android 4.x中一切正常)。

EDIT4:我的第三次修改不正确:现在几乎所有栏都有此行为。上面的onResume似乎是唯一一个从未受到影响的人。

2 个答案:

答案 0 :(得分:1)

我终于明白了代码的错误。

似乎更改SeekBar的最大值会触发彩条的重绘,同时触发重绘拇指。这可能是android 2.x中的一个错误(因为它不会发生在android 4.x中)。

要解决此问题,您只需在设置搜索栏上的进度之前设置的最大值。

在我的情况下,只有一些酒吧受到影响,因为我将NumericSeekBar的默认最大值设置为100,并且只有受影响的最大值不同的栏。

目前还不清楚为什么onResume中的视图无效,无法正确重新绘制小部件。

答案 1 :(得分:0)

我找到了重复方法:

final SeekBar seekBar = (SeekBar) findViewById(R.id.test_seekbar);
seekBar.setMax(4000);
seekBar.setProgress(1500);
new Thread(new Runnable() {
    public void run() {
        seekBar.setProgress(500);
    }
}).start();
for (int i = 0; i < 5000; i++) {
    seekBar.setProgress(2000);
}

上面的代码,在工作线程中称为ProgressBar#setProgress,它会导致错误。 Android官方文档建议在主线程中调用它,如下所示:

public class MyActivity extends Activity {
private static final int PROGRESS = 0x1;

private ProgressBar mProgress;
private int mProgressStatus = 0;

private Handler mHandler = new Handler();

protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    setContentView(R.layout.progressbar_activity);

    mProgress = (ProgressBar) findViewById(R.id.progress_bar);

    // Start lengthy operation in a background thread
    new Thread(new Runnable() {
        public void run() {
            while (mProgressStatus < 100) {
                mProgressStatus = doWork();

                // Update the progress bar
                mHandler.post(new Runnable() {
                    public void run() {
                        mProgress.setProgress(mProgressStatus);
                    }
                });               
            }
        }
    }).start();
}
}