android自定義支援橫豎方向切換seekbar控制元件
阿新 • • 發佈:2021-02-04
android自定義支援橫豎方向切換seekbar控制元件
先上執行效果截圖
下面貼上java程式碼
public class RodSeekBar extends SeekBar implements SeekBar.OnSeekBarChangeListener {
private final String TAG="RodSeekBar";
private final String VERTICAL = "vertical";
private final String HORIZONTAL = "horizontal";
private final String TOP = "top";
private final String BOTTOM = "bottom";
private String direction = HORIZONTAL;
private String verticalDirection = BOTTOM;
private int progressDisabledColor;
private int progressForeColor;
private int progressBackColor;
private int thumbEnableColor;
private int thumbDisableColor;
private OnSeekBarChangeListener mOnSeekBarChangeListener;
public RodSeekBar(Context context) {
super(context);
}
public RodSeekBar(Context context, AttributeSet attrs) {
super (context, attrs);
initData(attrs);
}
public RodSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initData(attrs);
}
private void initData( AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.RodSeekBar);
if (typedArray != null) {
progressDisabledColor = typedArray.getColor(R.styleable.RodSeekBar_progress_disable_color, Color.parseColor("#ffffff"));
progressBackColor = typedArray.getColor(R.styleable.RodSeekBar_progress_background_color, Color.parseColor("#232939"));
thumbEnableColor = typedArray.getColor(R.styleable.RodSeekBar_thumb_enable_color, Color.parseColor("#ffffff"));
thumbDisableColor = typedArray.getColor(R.styleable.RodSeekBar_thumb_disable_color, Color.parseColor("#ffffff"));
verticalDirection = typedArray.getString(R.styleable.RodSeekBar_rod_progress_vertical_direction);
direction = typedArray.getString(R.styleable.RodSeekBar_rod_progress_direction);
progressForeColor = typedArray.getColor(R.styleable.RodSeekBar_progress_enable_color, Color.parseColor("#00aa00"));
if (!VERTICAL.equals(direction) && !HORIZONTAL.equals(direction)) {
direction = HORIZONTAL;
}
if (!TOP.equals(verticalDirection) && !BOTTOM.equals(verticalDirection)) {
verticalDirection = BOTTOM;
}
typedArray.recycle();
}
Logger.d(TAG,""+direction);
setProgressDrawable(null);
setThumb(drawThumb(isEnabled()));
setThumbOffset(0);
setPadding(0, getPaddingTop(), 0, getBottom());
setSplitTrack(false);
super.setOnSeekBarChangeListener(this);
}
/**
* thumb的drawable
*
* @param isEnable
* @return
*/
private Drawable drawThumb(final boolean isEnable) {
//畫thumb
return new Drawable() {
@Override
public void draw(Canvas canvas) {
int height = RodSeekBar.this.getHeight();
int width = RodSeekBar.this.getWidth();
int max = RodSeekBar.this.getMax();
int progress = RodSeekBar.this.getProgress();
Paint paint = new Paint();
//是否可用顏色
if (isEnable) {
paint.setColor(thumbEnableColor);
} else {
paint.setColor(thumbDisableColor);
}
paint.setAntiAlias(true);
//根據方向繪製
if (HORIZONTAL.equals(direction)) {
float radius = (float) (height / 2.0);
float offset = (float) ((width - height) * 1.0 / max);
float x = progress * offset + radius;
canvas.drawCircle(x, radius, radius, paint);
} else {
float radius = (float) (width / 2.0);
float offset = (float) ((height - width) * 1.0 / max);
float y = progress * offset + radius;
//根據垂直方向繪製,從上開始、從下開始
if (TOP.equals(verticalDirection)) {
canvas.drawCircle(y, -radius, radius, paint);
} else {
canvas.drawCircle(height - y, -radius, radius, paint);
}
}
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
};
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
int max = getMax();
int progress = getProgress();
Paint paint = new Paint();
paint.setColor(progressBackColor);
paint.setAntiAlias(true);
RectF rect = new RectF(0, 0, width, height);
//根據方向繪製
if (HORIZONTAL.equals(direction)) {
//畫背景色
canvas.drawRoundRect(rect, height, height, paint);
//畫前景色
if (isEnabled()) {
paint.setColor(progressForeColor);
} else {
paint.setColor(progressDisabledColor);
}
float offset = (float) ((width - height) * 1.0 / max * progress + height);
rect = new RectF(0, 0, offset, height);
canvas.drawRoundRect(rect, height, height, paint);
} else {
//畫背景色
canvas.drawRoundRect(rect, width, width, paint);
//畫前景色
if (isEnabled()) {
paint.setColor(progressForeColor);
} else {
paint.setColor(progressDisabledColor);
}
float offset = (float) ((height - width) * 1.0 / max * progress + width);
//根據垂直方向繪製,從上開始、從下開始
if (TOP.equals(verticalDirection)) {
rect = new RectF(0, 0 , width, offset);
} else {
rect = new RectF(0, height, width, height - offset);
}
canvas.drawRoundRect(rect, width, width, paint);
canvas.rotate(90);
}
super.onDraw(canvas);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
if (VERTICAL.equals(direction)) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
//根據垂直方向響應,從上開始、從下開始
if (TOP.equals(verticalDirection)) {
setProgress((int) (getMax() * event.getY() / getHeight()));
} else {
setProgress((int) ((int) getMax() - (getMax() * event.getY() / getHeight())));
}
break;
default:
return super.onTouchEvent(event);
}
} else {
return super.onTouchEvent(event);
}
return true;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
@Override
public void setEnabled(boolean enable) {
super.setEnabled(enable);
setThumb(drawThumb(enable));
invalidate();
}
@Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
mOnSeekBarChangeListener = l;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
}
}
public int getProgressDisabledColor() {
return progressDisabledColor;
}
public void setProgressDisabledColor(int progressDisabledColor) {
this.progressDisabledColor = progressDisabledColor;
invalidate();
}
public int getProgressForeColor() {
return progressForeColor;
}
public void setProgressForeColor(int progressForeColor) {
this.progressForeColor = progressForeColor;
invalidate();
}
public int getProgressBackColor() {
return progressBackColor;
}
public void setProgressBackColor(int progressBackColor) {
this.progressBackColor = progressBackColor;
invalidate();
}
public int getThumbEnableColor() {
return thumbEnableColor;
}
public void setThumbEnableColor(int thumbEnableColor) {
this.thumbEnableColor = thumbEnableColor;
invalidate();
}
public int getThumbDisableColor() {
return thumbDisableColor;
}
public void setThumbDisableColor(int thumbDisableColor) {
this.thumbDisableColor = thumbDisableColor;
invalidate();
}
}
然後是attrs.xml檔案內容
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RodSeekBar">
<attr name="progress_enable_color" format="color" />
<attr name="progress_disable_color" format="color" />
<attr name="progress_background_color" format="color"/>
<attr name="thumb_enable_color" format="color" />
<attr name="thumb_disable_color" format="color" />
<attr name="rod_progress_direction" format="string"/>
<attr name="rod_progress_vertical_direction" format="string"/>
</declare-styleable>
</resources>
使用方法
app:rod_progress_direction=“horizontal” 橫向
app:rod_progress_direction=“vertical” 豎向
app:rod_progress_vertical_direction="top"豎向時thumb開始的方向top、bottom
app:progress_enable_color 進度條可用顏色
app:progress_disable_color 進度條不可用顏色
app:progress_background_color 背景色
app:thumb_enable_color 小圓點可用顏色
app:thumb_disable_color 小圓點不可用顏色