CircularSeekBar
- /**
- * @author Raghav Sood
- * @version 1
- * @date 26 January, 2013
- */
- package com.appaholics.circularseekbar;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.RectF;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- /**
- * The Class CircularSeekBar.
- */
- public class CircularSeekBar extends View {
- /** The context */
- private Context mContext;
- /** The listener to listen for changes */
- private OnSeekChangeListener mListener;
- /** The color of the progress ring */
- private Paint circleColor;
- /** the color of the inside circle. Acts as background color */
- private Paint innerColor;
- /** The progress circle ring background */
- private Paint circleRing;
- /** The angle of progress */
- private int angle = 0;
- /** The start angle (12 O'clock */
- private int startAngle = 270;
- /** The width of the progress ring */
- private int barWidth = 5;
- /** The width of the view */
- private int width;
- /** The height of the view */
- private int height;
- /** The maximum progress amount */
- private int maxProgress = 100;
- /** The current progress */
- private int progress;
- /** The progress percent */
- private int progressPercent;
- /** The radius of the inner circle */
- private float innerRadius;
- /** The radius of the outer circle */
- private float outerRadius;
- /** The circle's center X coordinate */
- private float cx;
- /** The circle's center Y coordinate */
- private float cy;
- /** The left bound for the circle RectF */
- private float left;
- /** The right bound for the circle RectF */
- private float right;
- /** The top bound for the circle RectF */
- private float top;
- /** The bottom bound for the circle RectF */
- private float bottom;
- /** The X coordinate for the top left corner of the marking drawable */
- private float dx;
- /** The Y coordinate for the top left corner of the marking drawable */
- private float dy;
- /** The X coordinate for 12 O'Clock */
- private float startPointX;
- /** The Y coordinate for 12 O'Clock */
- private float startPointY;
- /**
- * The X coordinate for the current position of the marker, pre adjustment
- * to center
- */
- private float markPointX;
- /**
- * The Y coordinate for the current position of the marker, pre adjustment
- * to center
- */
- private float markPointY;
- /**
- * The adjustment factor. This adds an adjustment of the specified size to
- * both sides of the progress bar, allowing touch events to be processed
- * more user friendly (yes, I know that's not a word)
- */
- private float adjustmentFactor = 100;
- /** The progress mark when the view isn't being progress modified */
- private Bitmap progressMark;
- /** The progress mark when the view is being progress modified. */
- private Bitmap progressMarkPressed;
- /** The flag to see if view is pressed */
- private boolean IS_PRESSED = false;
- /**
- * The flag to see if the setProgress() method was called from our own
- * View's setAngle() method, or externally by a user.
- */
- private boolean CALLED_FROM_ANGLE = false;
- private boolean SHOW_SEEKBAR = true;
- /** The rectangle containing our circles and arcs. */
- private RectF rect = new RectF();
- {
- mListener = new OnSeekChangeListener() {
- @Override
- public void onProgressChange(CircularSeekBar view, int newProgress) {
- }
- };
- circleColor = new Paint();
- innerColor = new Paint();
- circleRing = new Paint();
- circleColor.setColor(Color.parseColor("#ff33b5e5")); // Set default
- // progress
- // color to holo
- // blue.
- innerColor.setColor(Color.BLACK); // Set default background color to
- // black
- circleRing.setColor(Color.GRAY);// Set default background color to Gray
- circleColor.setAntiAlias(true);
- innerColor.setAntiAlias(true);
- circleRing.setAntiAlias(true);
- circleColor.setStrokeWidth(5);
- innerColor.setStrokeWidth(5);
- circleRing.setStrokeWidth(5);
- circleColor.setStyle(Paint.Style.FILL);
- }
- /**
- * Instantiates a new circular seek bar.
- *
- * @param context
- * the context
- * @param attrs
- * the attrs
- * @param defStyle
- * the def style
- */
- public CircularSeekBar(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mContext = context;
- initDrawable();
- }
- /**
- * Instantiates a new circular seek bar.
- *
- * @param context
- * the context
- * @param attrs
- * the attrs
- */
- public CircularSeekBar(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- initDrawable();
- }
- /**
- * Instantiates a new circular seek bar.
- *
- * @param context
- * the context
- */
- public CircularSeekBar(Context context) {
- super(context);
- mContext = context;
- initDrawable();
- }
- /**
- * Inits the drawable.
- */
- public void initDrawable() {
- progressMark = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.scrubber_control_normal_holo);
- progressMarkPressed = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.scrubber_control_pressed_holo);
- }
- /*
- * (non-Javadoc)
- *
- * @see android.view.View#onMeasure(int, int)
- */
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- width = getWidth(); // Get View Width
- height = getHeight();// Get View Height
- int size = (width > height) ? height : width; // Choose the smaller
- // between width and
- // height to make a
- // square
- cx = width / 2; // Center X for circle
- cy = height / 2; // Center Y for circle
- outerRadius = size / 2; // Radius of the outer circle
- innerRadius = outerRadius - barWidth; // Radius of the inner circle
- left = cx - outerRadius; // Calculate left bound of our rect
- right = cx + outerRadius;// Calculate right bound of our rect
- top = cy - outerRadius;// Calculate top bound of our rect
- bottom = cy + outerRadius;// Calculate bottom bound of our rect
- startPointX = cx; // 12 O'clock X coordinate
- startPointY = cy - outerRadius;// 12 O'clock Y coordinate
- markPointX = startPointX;// Initial locatino of the marker X coordinate
- markPointY = startPointY;// Initial locatino of the marker Y coordinate
- rect.set(left, top, right, bottom); // assign size to rect
- }
- /*
- * (non-Javadoc)
- *
- * @see android.view.View#onDraw(android.graphics.Canvas)
- */
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawCircle(cx, cy, outerRadius, circleRing);
- canvas.drawArc(rect, startAngle, angle, true, circleColor);
- canvas.drawCircle(cx, cy, innerRadius, innerColor);
- if(SHOW_SEEKBAR){
- dx = getXFromAngle();
- dy = getYFromAngle();
- drawMarkerAtProgress(canvas);
- }
- super.onDraw(canvas);
- }
- /**
- * Draw marker at the current progress point onto the given canvas.
- *
- * @param canvas
- * the canvas
- */
- public void drawMarkerAtProgress(Canvas canvas) {
- if (IS_PRESSED) {
- canvas.drawBitmap(progressMarkPressed, dx, dy, null);
- } else {
- canvas.drawBitmap(progressMark, dx, dy, null);
- }
- }
- /**
- * Gets the X coordinate of the arc's end arm's point of intersection with
- * the circle
- *
- * @return the X coordinate
- */
- public float getXFromAngle() {
- int size1 = progressMark.getWidth();
- int size2 = progressMarkPressed.getWidth();
- int adjust = (size1 > size2) ? size1 : size2;
- float x = markPointX - (adjust / 2);
- return x;
- }
- /**
- * Gets the Y coordinate of the arc's end arm's point of intersection with
- * the circle
- *
- * @return the Y coordinate
- */
- public float getYFromAngle() {
- int size1 = progressMark.getHeight();
- int size2 = progressMarkPressed.getHeight();
- int adjust = (size1 > size2) ? size1 : size2;
- float y = markPointY - (adjust / 2);
- return y;
- }
- /**
- * Get the angle.
- *
- * @return the angle
- */
- public int getAngle() {
- return angle;
- }
- /**
- * Set the angle.
- *
- * @param angle
- * the new angle
- */
- public void setAngle(int angle) {
- this.angle = angle;
- float donePercent = (((float) this.angle) / 360) * 100;
- float progress = (donePercent / 100) * getMaxProgress();
- setProgressPercent(Math.round(donePercent));
- CALLED_FROM_ANGLE = true;
- setProgress(Math.round(progress));
- }
- /**
- * Sets the seek bar change listener.
- *
- * @param listener
- * the new seek bar change listener
- */
- public void setSeekBarChangeListener(OnSeekChangeListener listener) {
- mListener = listener;
- }
- /**
- * Gets the seek bar change listener.
- *
- * @return the seek bar change listener
- */
- public OnSeekChangeListener getSeekBarChangeListener() {
- return mListener;
- }
- /**
- * Gets the bar width.
- *
- * @return the bar width
- */
- public int getBarWidth() {
- return barWidth;
- }
- /**
- * Sets the bar width.
- *
- * @param barWidth
- * the new bar width
- */
- public void setBarWidth(int barWidth) {
- this.barWidth = barWidth;
- }
- /**
- * The listener interface for receiving onSeekChange events. The class that
- * is interested in processing a onSeekChange event implements this
- * interface, and the object created with that class is registered with a
- * component using the component's
- * <code>setSeekBarChangeListener(OnSeekChangeListener)<code> method. When
- * the onSeekChange event occurs, that object's appropriate
- * method is invoked.
- *
- * @see OnSeekChangeEvent
- */
- public interface OnSeekChangeListener {
- /**
- * On progress change.
- *
- * @param view
- * the view
- * @param newProgress
- * the new progress
- */
- public void onProgressChange(CircularSeekBar view, int newProgress);
- }
- /**
- * Gets the max progress.
- *
- * @return the max progress
- */
- public int getMaxProgress() {
- return maxProgress;
- }
- /**
- * Sets the max progress.
- *
- * @param maxProgress
- * the new max progress
- */
- public void setMaxProgress(int maxProgress) {
- this.maxProgress = maxProgress;
- }
- /**
- * Gets the progress.
- *
- * @return the progress
- */
- public int getProgress() {
- return progress;
- }
- /**
- * Sets the progress.
- *
- * @param progress
- * the new progress
- */
- public void setProgress(int progress) {
- if (this.progress != progress) {
- this.progress = progress;
- if (!CALLED_FROM_ANGLE) {
- int newPercent = (this.progress * 100) / this.maxProgress;
- int newAngle = (newPercent * 360) / 100 ;
- this.setAngle(newAngle);
- this.setProgressPercent(newPercent);
- }
- mListener.onProgressChange(this, this.getProgress());
- CALLED_FROM_ANGLE = false;
- }
- }
- /**
- * Gets the progress percent.
- *
- * @return the progress percent
- */
- public int getProgressPercent() {
- return progressPercent;
- }
- /**
- * Sets the progress percent.
- *
- * @param progressPercent
- * the new progress percent
- */
- public void setProgressPercent(int progressPercent) {
- this.progressPercent = progressPercent;
- }
- /**
- * Sets the ring background color.
- *
- * @param color
- * the new ring background color
- */
- public void setRingBackgroundColor(int color) {
- circleRing.setColor(color);
- }
- /**
- * Sets the back ground color.
- *
- * @param color
- * the new back ground color
- */
- public void setBackGroundColor(int color) {
- innerColor.setColor(color);
- }
- /**
- * Sets the progress color.
- *
- * @param color
- * the new progress color
- */
- public void setProgressColor(int color) {
- circleColor.setColor(color);
- }
- /*
- * (non-Javadoc)
- *
- * @see android.view.View#onTouchEvent(android.view.MotionEvent)
- */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- boolean up = false;
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- moved(x, y, up);
- break;
- case MotionEvent.ACTION_MOVE:
- moved(x, y, up);
- break;
- case MotionEvent.ACTION_UP:
- up = true;
- moved(x, y, up);
- break;
- }
- return true;
- }
- /**
- * Moved.
- *
- * @param x
- * the x
- * @param y
- * the y
- * @param up
- * the up
- */
- private void moved(float x, float y, boolean up) {
- float distance = (float) Math.sqrt(Math.pow((x - cx), 2) + Math.pow((y - cy), 2));
- if (distance < outerRadius + adjustmentFactor && distance > innerRadius - adjustmentFactor && !up) {
- IS_PRESSED = true;
- markPointX = (float) (cx + outerRadius * Math.cos(Math.atan2(x - cx, cy - y) - (Math.PI /2)));
- markPointY = (float) (cy + outerRadius * Math.sin(Math.atan2(x - cx, cy - y) - (Math.PI /2)));
- float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(x - cx, cy - y)) + 360.0)) % 360.0);
- // and to make it count 0-360
- if (degrees < 0) {
- degrees += 2 * Math.PI;
- }
- setAngle(Math.round(degrees));
- invalidate();
- } else {
- IS_PRESSED = false;
- invalidate();
- }
- }
- /**
- * Gets the adjustment factor.
- *
- * @return the adjustment factor
- */
- public float getAdjustmentFactor() {
- return adjustmentFactor;
- }
- /**
- * Sets the adjustment factor.
- *
- * @param adjustmentFactor
- * the new adjustment factor
- */
- public void setAdjustmentFactor(float adjustmentFactor) {
- this.adjustmentFactor = adjustmentFactor;
- }
- /**
- * To display seekbar
- */
- public void ShowSeekBar() {
- SHOW_SEEKBAR = true;
- }
- /**
- * To hide seekbar
- */
- public void hideSeekBar() {
- SHOW_SEEKBAR = false;
- }
- }
CircularSeekBar的更多相关文章
- android CircularSeekBar
Android 中的 seekBar会被开发者经常用到,用的最多的空拍是控制音量.但是有时后为了更好的UI效果,横着的拖动条不能满足我们项目的需要,我们可能需要竖直的或者圆形的拖动条,那这两种样式的类 ...
- wesome-android
awesome-android Introduction android libs from github System requirements Android Notice If the lib ...
随机推荐
- MongoDB学习笔记-06 数据库命令、固定集合、GridFS、javascript脚本
介绍MongoDB支持的一些高级功能: 数据库命令 固定大小的集合 GridFS存储大文件 MongoDB对服务端JavaScript的支持 数据库命令 命令的原理 MongoDB中的命令其实是作为一 ...
- 8.2 辅助 xUtils 3.0
主要有四大模块: DbUtils模块: android中的orm(对象关系映射)框架,一行代码就可以进行增删改查: 支持事务,默认关闭: 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL ...
- HashMap LinkedHashMap源码分析笔记
MapClassDiagram
- HttpURLConnection使用getInputStream无法执行
url = new URL(urlStr); urlConn = (HttpURLConnection) url.openConnection(); // 设置请求方式为"GET" ...
- 3.一起来学hibernate之配置文件2
之前的映射文件配置都是简单的.基础的配置,只涉及到单个javabean,对于单个javabean的增删改查都能很好的.简单的去完成. 但是知道简单配置远远不够,并不能完成很多复杂的情况,比如对象与对象 ...
- Ubuntu 12.04 改造指南
文章转自:http://www.lupaworld.com/article-217719-1.html 升级12.04已经有一段时间了.作为一个从08年就开始用Ubuntu的老用户,我觉得作为一个LT ...
- 【设计模式之单例模式InJava】
1. 单例模式 1.1饿汉式(开发常用) class SingleFirst { /* 添加其他成员信息 */ private static SingleFirst s1 = new SingleFi ...
- anyncTask的3个参数
AnyncTask异步处理数据并将数据应用到视图的操作场合 一 其中包含这几个方法 1 onPreExcute() 初始化控件,例如进度条2 doInBackground() 具体的执行动作请求数据 ...
- 微信公共平台开发-(.net实现)4--发送图文消息
之前说了让微信发送给关注我们的粉丝普通的文本信息,下面我们来看看如何发送图文信息,需要注意的是这里说的是,让微信发给我们,而不是我们拍个图片发给微信处理,上传图片在以后的再讲.下面是发送图文消息的函数 ...
- listview(3、动态刷新)
listview的动态刷新主要是调用adapter的notifyDataSetChanged. 在下面的例子中除了记录正常的刷新外,还记录一种错误的情况(注释掉的),作为备忘. notifyDataS ...