自定义Android SeekBar有无形进度条,为什么?

时间:2014-07-09 22:31:23

标签: seekbar android-progressbar

您好我正在编写自定义搜索栏以显示拇指上的进度。我正在使用的方法是覆盖setOnProgressChangeListener方法,并将其替换为一个新的侦听器,其代码用拇指替换拇指,该拇指上有文本。它工作正常,除了进度条消失了!这是我的自定义类:

public class ProgressDisplayingSeekBar extends SeekBar {
  private static final String TAG = ProgressDisplayingSeekBar.class.getSimpleName();

  private Paint mTextPaint;
  private Bitmap mOriginalThumbBitmap;

  private static OnSeekBarChangeListener DummyOnSeekBarProgressChangedListener =
      new OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
          // Dummy
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
          // Dummy
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
          // Dummy
        }
      };

  public ProgressDisplayingSeekBar(Context context) {
    this(context, null);
  }

  public ProgressDisplayingSeekBar(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public ProgressDisplayingSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mTextPaint.setColor(getResources().getColor(R.color.text_color_dark_bg));
    mTextPaint.setTextSize(getResources().getDimension(R.dimen.progress_button_text_size));
    mTextPaint.setTypeface(Typeface.create("sans-serif-condensed", Typeface.NORMAL));

    initThumb();
    setOnSeekBarChangeListener(DummyOnSeekBarProgressChangedListener);
  }

  private void initThumb() {
    Drawable thumbDrawable = this.getThumb();
    mOriginalThumbBitmap = Bitmap.createBitmap(thumbDrawable.getIntrinsicWidth(),
        thumbDrawable.getIntrinsicHeight(),
        Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(mOriginalThumbBitmap);
    thumbDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    thumbDrawable.draw(canvas);
    updateThumbWithProgressDisplay();
  }

  @Override
  public void setOnSeekBarChangeListener(final OnSeekBarChangeListener onSeekBarChangeListener) {
    OnSeekBarChangeListener progressDisplayingOnSeekBarChangeListener =
        new OnSeekBarChangeListener() {
          @Override
          public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            onSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
            updateThumbWithProgressDisplay();
          }

          @Override
          public void onStartTrackingTouch(SeekBar seekBar) {
            onSeekBarChangeListener.onStartTrackingTouch(seekBar);
          }

          @Override
          public void onStopTrackingTouch(SeekBar seekBar) {
            onSeekBarChangeListener.onStopTrackingTouch(seekBar);
          }
        };

    super.setOnSeekBarChangeListener(progressDisplayingOnSeekBarChangeListener);
  }

  private void updateThumbWithProgressDisplay() {
    Bitmap newThumbBitmap = mOriginalThumbBitmap.copy(Bitmap.Config.ARGB_8888, true);
    Canvas canvas = new Canvas(newThumbBitmap);
    String progressDisplaytext = Integer.toString(this.getProgress());
    int width = (int) mTextPaint.measureText(progressDisplaytext);
    int y = (int) ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2));
    canvas.drawText(progressDisplaytext,
        (newThumbBitmap.getWidth() - width) / 2,
        y,
        mTextPaint);
    this.setThumb(new BitmapDrawable(getResources(), newThumbBitmap));
  }
}

如何获取原始进度条(带蓝色填充的灰线)?

修改

我最终不得不使用我自己的进度drawable,如下所示:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@android:id/background">
      <shape>
        <gradient
            android:angle="90"
            android:startColor="#00b0b0b0"
            android:centerColor="#b0b0b0"
            android:endColor="#00b0b0b0"/>
      </shape>
  </item>

  <item android:id="@android:id/secondaryProgress">
    <clip>
      <shape>
        <solid android:color="@color/light_blue"/>
      </shape>
    </clip>
  </item>

  <item android:id="@android:id/progress">
    <clip>
      <shape>
        <solid android:color="@color/light_blue"/>
      </shape>
    </clip>
  </item>
</layer-list>

并设置修复Progress Drawable的XML:

      android:minHeight="4dp"
      android:maxHeight="4dp"
      android:thumb="@drawable/my_thumb"
      android:progressDrawable="@drawable/my_progress"/>

1 个答案:

答案 0 :(得分:0)

我认为这个问题与您的自定义SeekBar类中的构造函数有关。在多个StackOverflow答案中看到这种方法后,我以同样的方式设置了我的方法:

public ProgressDisplayingSeekBar(Context context) {
    this(context, null);
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    // setup code goes here
}

但是我感觉第二个构造函数,它需要将XML属性传递给SeekBar,但运行不正确。我改成了这个:

public ProgressDisplayingSeekBar(Context context) {
    super(context, null, 0);
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs) {
    super(context, attrs, 0);
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    // setup code goes here
}

但仍然没有运气。然后我尝试了这个:

public ProgressDisplayingSeekBar(Context context) {
    super(context);
    this.init();
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.init();
}

public ProgressDisplayingSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.init();
}

public void init() {
    // setup code goes here
}

成功!为设置代码创建单独的方法比使用现有的构造函数方法稍微优雅一点,但如果您想使用默认的滑块图形,这是一个简单的修复。

我不知道提倡其他方法之一的答案是错误的,或者自早期Android版本以来是否已经发生变化,或其他方式。