Android 中的 seekBar会被开发者经常用到,用的最多的空拍是控制音量。但是有时后为了更好的UI效果,横着的拖动条不能满足我们项目的需要,我们可能需要竖直的或者圆形的拖动条,那这两种样式的类SeekBar的效果如何实现呢,接下来小编会一一给出效果和源码。接下来,先说一说圆形的效果吧,有图有真相,请看图:

看过图之后是不是觉得很炫,自己赞一个,下面给出源码:
/values/attr.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
-
- <declare-styleable name="HoloCircleSeekBar">
- <attr name="wheel_size" format="integer" />
- <attr name="pointer_size" format="integer" />
- <attr name="max" format="integer"></attr>
- <attr name="show_text" format="boolean"></attr>
- <attr name="start_angle" format="integer"></attr>
- <attr name="end_angle" format="integer"></attr>
- <attr name="text_size" format="integer"></attr>
- <attr name="init_position" format="integer"></attr>
- <attr name="color" format="string"></attr>
- <attr name="wheel_active_color" format="string"></attr>
- <attr name="wheel_unactive_color" format="string"></attr>
- <attr name="pointer_color" format="string"></attr>
- <attr name="pointer_halo_color" format="string"></attr>
- <attr name="text_color" format="string"></attr>
- </declare-styleable>
-
- </resources>
ZJBCircleSeekBar.java:
- package com.example.circleseekbar;
-
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.graphics.RectF;
- import android.graphics.SweepGradient;
- import android.os.Bundle;
- import android.os.Parcelable;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
-
-
- public class ZJBCircleSeekBar extends View {
-
- private static final String STATE_PARENT = "parent";
- private static final String STATE_ANGLE = "angle";
-
-
- private OnCircleSeekBarChangeListener mOnCircleSeekBarChangeListener;
-
-
- private Paint mColorWheelPaint;
-
-
- private Paint mPointerHaloPaint;
-
-
- private Paint mPointerColor;
-
-
- private final int mColorWheelStrokeWidth = 10;
-
-
- private final int mPointerRadius = 80;
-
-
- private RectF mColorWheelRectangle = new RectF();
-
-
- private boolean mUserIsMovingPointer = false;
-
-
- private float mTranslationOffset;
-
-
- private float mColorWheelRadius;
-
- private float mAngle;
- private String text;
- private int conversion = 0;
- private int max = 100;
- private String color_attr;
- private SweepGradient s;
- private Paint mArcColor;
- private String wheel_color_attr, wheel_unactive_color_attr,
- pointer_color_attr, pointer_halo_color_attr;
- private int init_position;
- private boolean block_end = false;
- private float lastX;
- private int last_radians = 0;
- private boolean block_start = false;
-
- private int arc_finish_radians = 270;
-
- private int start_arc = 135;
-
- private float[] pointerPosition;
- private Paint mColorCenterHalo;
- private RectF mColorCenterHaloRectangle = new RectF();
- private int end_wheel;
-
- private Bitmap pointerBitmap;
- private boolean show_text = false;
-
- public ZJBCircleSeekBar(Context context) {
- super(context);
- init(null, 0);
- }
-
- public ZJBCircleSeekBar(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(attrs, 0);
- }
-
- public ZJBCircleSeekBar(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(attrs, defStyle);
- }
-
- private void init(AttributeSet attrs, int defStyle) {
- final TypedArray a = getContext().obtainStyledAttributes(attrs,
- R.styleable.HoloCircleSeekBar, defStyle, 0);
-
- initAttributes(a);
-
- a.recycle();
-
-
- mColorWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mColorWheelPaint.setShader(s);
- mColorWheelPaint.setColor(Color.BLACK);
- mColorWheelPaint.setStyle(Paint.Style.STROKE);
- mColorWheelPaint.setStrokeWidth(mColorWheelStrokeWidth);
-
- mColorCenterHalo = new Paint(Paint.ANTI_ALIAS_FLAG);
- mColorCenterHalo.setColor(Color.CYAN);
- mColorCenterHalo.setAlpha(0xCC);
-
-
-
-
- mPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPointerHaloPaint.setColor(Color.GREEN);
- mPointerHaloPaint.setStrokeWidth(mPointerRadius + 10);
-
-
- pointerBitmap = BitmapFactory.decodeResource(this.getResources(),
- R.drawable.pointer);
-
- mPointerColor = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPointerColor.setStrokeWidth(mPointerRadius);
-
-
- mPointerColor.setColor(Color.GREEN);
-
-
- mArcColor = new Paint(Paint.ANTI_ALIAS_FLAG);
- mArcColor.setColor(Color.GREEN);
- mArcColor.setStyle(Paint.Style.STROKE);
- mArcColor.setStrokeWidth(mColorWheelStrokeWidth);
-
- arc_finish_radians = (int) calculateAngleFromText(init_position) - 90;
-
- if (arc_finish_radians > end_wheel)
- arc_finish_radians = end_wheel;
- mAngle = calculateAngleFromRadians(arc_finish_radians > end_wheel ? end_wheel
- : arc_finish_radians);
- text = String.valueOf(calculateTextFromAngle(arc_finish_radians));
-
- invalidate();
- }
-
- private void initAttributes(TypedArray a) {
-
- max = a.getInteger(R.styleable.HoloCircleSeekBar_max, 100);
-
- color_attr = a.getString(R.styleable.HoloCircleSeekBar_color);
- wheel_color_attr = a
- .getString(R.styleable.HoloCircleSeekBar_wheel_active_color);
- wheel_unactive_color_attr = a
- .getString(R.styleable.HoloCircleSeekBar_wheel_unactive_color);
- pointer_color_attr = a
- .getString(R.styleable.HoloCircleSeekBar_pointer_color);
- pointer_halo_color_attr = a
- .getString(R.styleable.HoloCircleSeekBar_pointer_halo_color);
-
- a.getString(R.styleable.HoloCircleSeekBar_text_color);
-
- a.getInteger(R.styleable.HoloCircleSeekBar_text_size, 95);
-
- init_position = a.getInteger(
- R.styleable.HoloCircleSeekBar_init_position, 0);
-
- start_arc = a.getInteger(R.styleable.HoloCircleSeekBar_start_angle, 0);
- end_wheel = a.getInteger(R.styleable.HoloCircleSeekBar_end_angle, 360);
-
- show_text = a.getBoolean(R.styleable.HoloCircleSeekBar_show_text, true);
-
- last_radians = end_wheel;
-
- if (init_position < start_arc)
- init_position = calculateTextFromStartAngle(start_arc);
-
-
-
- if (color_attr != null) {
- try {
- Color.parseColor(color_attr);
- } catch (IllegalArgumentException e) {
- }
- Color.parseColor(color_attr);
- } else {
- }
-
- if (wheel_color_attr != null) {
- try {
- Color.parseColor(wheel_color_attr);
- } catch (IllegalArgumentException e) {
- }
-
- } else {
- }
- if (wheel_unactive_color_attr != null) {
- try {
- Color.parseColor(wheel_unactive_color_attr);
- } catch (IllegalArgumentException e) {
- }
-
- } else {
- }
-
- if (pointer_color_attr != null) {
- try {
- Color.parseColor(pointer_color_attr);
- } catch (IllegalArgumentException e) {
- }
-
- } else {
- }
-
- if (pointer_halo_color_attr != null) {
- try {
- Color.parseColor(pointer_halo_color_attr);
- } catch (IllegalArgumentException e) {
- }
-
- } else {
- }
-
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.translate(mTranslationOffset, mTranslationOffset);
-
-
- canvas.drawArc(mColorWheelRectangle, start_arc + 270, end_wheel
- - (start_arc), false, mColorWheelPaint);
-
-
- canvas.drawArc(mColorWheelRectangle, start_arc + 270,
- (arc_finish_radians) > (end_wheel) ? end_wheel - (start_arc)
- : arc_finish_radians - start_arc, false, mArcColor);
-
-
-
-
-
-
-
-
-
-
-
-
- canvas.drawBitmap(pointerBitmap, pointerPosition[0] - 50,
- pointerPosition[1] - 115, null);
-
-
- Paint pai = new Paint();
- pai.setColor(Color.BLACK);
- pai.setTextSize(50);
- canvas.drawText(text, pointerPosition[0] - 30, pointerPosition[1] - 40,
- pai);
-
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int height = getDefaultSize(getSuggestedMinimumHeight(),
- heightMeasureSpec);
- int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
- int min = Math.min(width, height);
- setMeasuredDimension(min, min);
-
- mTranslationOffset = min * 0.5f;
- mColorWheelRadius = mTranslationOffset - mPointerRadius;
-
- mColorWheelRectangle.set(-mColorWheelRadius, -mColorWheelRadius,
- mColorWheelRadius, mColorWheelRadius);
-
- mColorCenterHaloRectangle.set(-mColorWheelRadius / 2,
- -mColorWheelRadius / 2, mColorWheelRadius / 2,
- mColorWheelRadius / 2);
-
- pointerPosition = calculatePointerPosition(mAngle);
-
- }
-
- private int calculateTextFromAngle(float angle) {
- float m = angle - start_arc;
-
- float f = (float) ((end_wheel - start_arc) / m);
-
- return (int) (max / f);
- }
-
- private int calculateTextFromStartAngle(float angle) {
- float m = angle;
-
- float f = (float) ((end_wheel - start_arc) / m);
-
- return (int) (max / f);
- }
-
- private double calculateAngleFromText(int position) {
- if (position == 0 || position >= max)
- return (float) 90;
-
- double f = (double) max / (double) position;
-
- double f_r = 360 / f;
-
- double ang = f_r + 90;
-
- return ang;
-
- }
-
- private int calculateRadiansFromAngle(float angle) {
- float unit = (float) (angle / (2 * Math.PI));
- if (unit < 0) {
- unit += 1;
- }
- int radians = (int) ((unit * 360) - ((360 / 4) * 3));
- if (radians < 0)
- radians += 360;
- return radians;
- }
-
- private float calculateAngleFromRadians(int radians) {
- return (float) (((radians + 270) * (2 * Math.PI)) / 360);
- }
-
- public int getValue() {
- return conversion;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
-
- float x = event.getX() - mTranslationOffset;
- float y = event.getY() - mTranslationOffset;
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
-
- mAngle = (float) java.lang.Math.atan2(y, x);
-
- block_end = false;
- block_start = false;
- mUserIsMovingPointer = true;
-
- arc_finish_radians = calculateRadiansFromAngle(mAngle);
-
- if (arc_finish_radians > end_wheel) {
- arc_finish_radians = end_wheel;
- block_end = true;
- }
-
- if (!block_end && !block_start) {
- text = String
- .valueOf(calculateTextFromAngle(arc_finish_radians));
- pointerPosition = calculatePointerPosition(mAngle);
- invalidate();
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (mUserIsMovingPointer) {
- mAngle = (float) java.lang.Math.atan2(y, x);
-
- int radians = calculateRadiansFromAngle(mAngle);
-
- if (last_radians > radians && radians < (360 / 6) && x > lastX
- && last_radians > (360 / 6)) {
-
- if (!block_end && !block_start)
- block_end = true;
-
- } else if (last_radians >= start_arc
- && last_radians <= (360 / 4) && radians <= (360 - 1)
- && radians >= ((360 / 4) * 3) && x < lastX) {
- if (!block_start && !block_end)
- block_start = true;
-
- } else if (radians >= end_wheel && !block_start
- && last_radians < radians) {
- block_end = true;
- } else if (radians < end_wheel && block_end
- && last_radians > end_wheel) {
- block_end = false;
- } else if (radians < start_arc && last_radians > radians
- && !block_end) {
- block_start = true;
- } else if (block_start && last_radians < radians
- && radians > start_arc && radians < end_wheel) {
- block_start = false;
- }
-
- if (block_end) {
-
- arc_finish_radians = end_wheel - 1;
- text = String.valueOf(0);
- mAngle = calculateAngleFromRadians(arc_finish_radians);
- pointerPosition = calculatePointerPosition(mAngle);
- } else if (block_start) {
-
- arc_finish_radians = start_arc;
- mAngle = calculateAngleFromRadians(arc_finish_radians);
- text = String.valueOf(0);
- pointerPosition = calculatePointerPosition(mAngle);
- } else {
-
- arc_finish_radians = calculateRadiansFromAngle(mAngle);
- text = String
- .valueOf(calculateTextFromAngle(arc_finish_radians));
- pointerPosition = calculatePointerPosition(mAngle);
- }
- invalidate();
- if (mOnCircleSeekBarChangeListener != null)
- mOnCircleSeekBarChangeListener.onProgressChanged(this,
- Integer.parseInt(text), true);
-
- last_radians = radians;
-
- }
- break;
- case MotionEvent.ACTION_UP:
- mUserIsMovingPointer = false;
- break;
- }
- if (event.getAction() == MotionEvent.ACTION_MOVE && getParent() != null) {
- getParent().requestDisallowInterceptTouchEvent(true);
- }
- lastX = x;
-
- return true;
- }
-
-
- private float[] calculatePointerPosition(float angle) {
-
-
- float x = (float) (mColorWheelRadius * Math.cos(angle));
- float y = (float) (mColorWheelRadius * Math.sin(angle));
-
- return new float[] { x, y };
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- Parcelable superState = super.onSaveInstanceState();
-
- Bundle state = new Bundle();
- state.putParcelable(STATE_PARENT, superState);
- state.putFloat(STATE_ANGLE, mAngle);
-
- return state;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- Bundle savedState = (Bundle) state;
-
- Parcelable superState = savedState.getParcelable(STATE_PARENT);
- super.onRestoreInstanceState(superState);
-
- mAngle = savedState.getFloat(STATE_ANGLE);
- arc_finish_radians = calculateRadiansFromAngle(mAngle);
- text = String.valueOf(calculateTextFromAngle(arc_finish_radians));
- pointerPosition = calculatePointerPosition(mAngle);
-
- }
-
- public void setOnSeekBarChangeListener(OnCircleSeekBarChangeListener l) {
- mOnCircleSeekBarChangeListener = l;
- }
-
- public interface OnCircleSeekBarChangeListener {
-
- public abstract void onProgressChanged(ZJBCircleSeekBar seekBar,
- int progress, boolean fromUser);
-
- }
-
- }
/layout/activity_main.xml:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_gravity="center_horizontal"
- tools:context=".MainActivity" >
-
- <TextView
- android:id="@+id/text"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="80dp"
- android:gravity="center_horizontal"
- android:textSize="60sp"
- android:textColor="#ffff0000"
- />
-
- <com.example.circleseekbar.HoloCircleSeekBar
- android:id="@+id/c"
- android:layout_width="500px"
- android:layout_height="500px"
- android:layout_centerInParent="true" />
-
- </RelativeLayout>
MainActivity.java:
- package com.example.circleseekbar;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.TextView;
-
- import com.example.circleseekbar.ZJBCircleSeekBar.OnCircleSeekBarChangeListener;
-
- public class MainActivity extends Activity implements
- OnCircleSeekBarChangeListener {
-
- private ZJBCircleSeekBar circleSeekBar;
- TextView textView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- circleSeekBar = (ZJBCircleSeekBar) findViewById(R.id.c);
- textView = (TextView) findViewById(R.id.text);
- circleSeekBar.setOnSeekBarChangeListener(this);
- }
-
- @Override
- public void onProgressChanged(ZJBCircleSeekBar seekBar, int progress,
- boolean fromUser) {
-
- textView.setText(progress + "");
- }
-
- }
小编很辛苦,请尊重菜鸟的劳动成果,转载请注明出处:http://blog.csdn.net/zjbpku/article/details/10140815
android CircularSeekBar
原文:http://www.cnblogs.com/Free-Thinker/p/4507795.html