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;/** * @author zjbpku * @time 2013-08-21 * @blog http://blog.csdn.net/zjbpku */public class ZJBCircleSeekBar extends View {/** * 保存状态 */private static final String STATE_PARENT = "parent";private static final String STATE_ANGLE = "angle";/*** * 事件监听 */private OnCircleSeekBarChangeListener mOnCircleSeekBarChangeListener;/** * 圆环paint对象 */private Paint mColorWheelPaint;/** * 游标paint对象 */private Paint mPointerHaloPaint;/** * 游标为图画时的paint对象 */private Paint mPointerColor;/** * 圆环的宽度 */private final int mColorWheelStrokeWidth = 10;/** * 游标所在圆环半径 */private final int mPointerRadius = 80;/** * The rectangle enclosing the color wheel. */private RectF mColorWheelRectangle = new RectF();/** * {@code true} 点击游标 {@code false} 停止 *  * @see #onTouchEvent(MotionEvent) */private boolean mUserIsMovingPointer = false;/** *  */private float mTranslationOffset;/** * 圆环半径 Note: (Re)在onMeasure计算{@link #onMeasure(int, int)} */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();// mAngle = (float) (-Math.PI / 2);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);// mColorCenterHalo.setStyle(Paint.Style.STROKE);// mColorCenterHalo.setStrokeWidth(mColorCenterHaloRectangle.width() /// 2);mPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPointerHaloPaint.setColor(Color.GREEN);mPointerHaloPaint.setStrokeWidth(mPointerRadius + 10);// mPointerHaloPaint.setAlpha(150);// 游标图片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);// mAngle = (float) calculateAngleFromText(init_position);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 {}}@Overrideprotected 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.drawCircle(pointerPosition[0], pointerPosition[1],// mPointerRadius, mPointerHaloPaint);//// canvas.drawCircle(pointerPosition[0], pointerPosition[1],// (float) (mPointerRadius / 1.2), mPointerColor);// 游标为方形// canvas.drawRect(pointerPosition[0] - 50, pointerPosition[1] - 30,// pointerPosition[0] + 50, pointerPosition[1] + 30, mPointerColor);// 游标为图片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);}@Overrideprotected 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;}@Overridepublic boolean onTouchEvent(MotionEvent event) {// Convert coordinates to our internal coordinate systemfloat x = event.getX() - mTranslationOffset;float y = event.getY() - mTranslationOffset;switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// Check whether the user pressed on (or near) the pointermAngle = (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 {// text = String.valueOf(calculateTextFromAngle(mAngle));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;}/** * Calculate the pointer's coordinates on the color wheel using the supplied * angle. *  * @param angle *            The position of the pointer expressed as angle (in rad). *  * @return The coordinates of the pointer's center in our internal *         coordinate system. */private float[] calculatePointerPosition(float angle) {// if (calculateRadiansFromAngle(angle) > end_wheel)// angle = calculateAngleFromRadians(end_wheel);float x = (float) (mColorWheelRadius * Math.cos(angle));float y = (float) (mColorWheelRadius * Math.sin(angle));return new float[] { x, y };}@Overrideprotected Parcelable onSaveInstanceState() {Parcelable superState = super.onSaveInstanceState();Bundle state = new Bundle();state.putParcelable(STATE_PARENT, superState);state.putFloat(STATE_ANGLE, mAngle);return state;}@Overrideprotected 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;/** * @author zjbpku * @time 2013-08-21 * @blog http://blog.csdn.net/zjbpku */public class MainActivity extends Activity implementsOnCircleSeekBarChangeListener {private ZJBCircleSeekBar circleSeekBar;TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);circleSeekBar = (ZJBCircleSeekBar) findViewById(R.id.c);textView = (TextView) findViewById(R.id.text);circleSeekBar.setOnSeekBarChangeListener(this);}@Overridepublic void onProgressChanged(ZJBCircleSeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubtextView.setText(progress + "");}}
小编很辛苦,请尊重菜鸟的劳动成果,转载请注明出处: http://blog.csdn.net/zjbpku/article/details/10140815

更多相关文章

  1. Android(安卓)仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应
  2. Android(安卓)DragAndDrop API 拖拽效果 交换ListView的Item值
  3. 关于Android系统的局域网广播的相关东东
  4. Android(安卓)模仿Path 的左右拉动菜单效果
  5. Drawable的Tint变色(让Android也能有iOS那么方便的图片色调转换)
  6. android 遮罩层效果
  7. android 一张图片实现 ImageView 实现 点击效果 图片明度变化
  8. Android墨迹3.0特性介绍效果实现——做一个垂直滚动的Layout
  9. 14—深入Animation,在SurfaceView中照样使用Android—Tween Anim

随机推荐

  1. android 显示gif图片实例详解
  2. android 和云计算
  3. 如何脱离Android源码环境编译aapt
  4. android listview 一行高亮
  5. java.lang.NullPointerException空指针问
  6. Android(安卓)XML解析学习——Pull方式
  7. 转:一个Demo学完Android中所有的服务
  8. 转:关于android多任务同时下载的一点心得
  9. [置顶] 我的Android进阶之旅------>关于a
  10. 开发android应该注意的