1.效果图:
2.自定义的音量旋钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:MCCP_SeekBar="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
<com.example.longshine.zname.MCCP_SeekBar
android:id="@+id/id_mcl_seekbar_main_valume"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_gravity="center_vertical"
android:thumb="@drawable/mhs_seekbar_thumb"
MCCP_SeekBar:mccp_end_angle="45"
MCCP_SeekBar:mccp_max="46"
MCCP_SeekBar:mccp_seekbar_bg_color="@color/mc_seekbar_bg_color"
MCCP_SeekBar:mccp_seekbar_bg_width="2dp"
MCCP_SeekBar:mccp_seekbar_inside_color="@color/mc_seekbar_inside_color"
MCCP_SeekBar:mccp_seekbar_outside_color="@color/mc_seekbar_outside_color"
MCCP_SeekBar:mccp_seekbar_progress_bg_color="@color/mc_seekbar_progress_bg_color"
MCCP_SeekBar:mccp_seekbar_progress_thumb_r="4dp"
MCCP_SeekBar:mccp_seekbar_thumb_color="@color/mc_seekbar_thumb_color"
MCCP_SeekBar:mccp_start_angle="135" />
<TextView
android:id="@+id/id_b_valume"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_centerInParent="true"
android:clickable="false"
android:singleLine="true"
android:textColor="@color/text_color_high_set"
android:textSize="60sp"
android:textAllCaps="false"
/>
</RelativeLayout>
</LinearLayout>
3.图片资源mhs_seekbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="false"
android:state_pressed="false"
android:drawable="@drawable/mhs_thumb_normal"/>
<item
android:state_activated="true"
android:state_pressed="false"
android:drawable="@drawable/mhs_thumb_normal" />
<item
android:state_activated="false"
android:state_pressed="true"
android:drawable="@drawable/mhs_thumb_normal"/>
<item
android:state_activated="true"
android:state_pressed="true"
android:drawable="@drawable/mhs_thumb_normal" />
</selector>
4.创建一个attr:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MCCP_SeekBar">
<attr name="android:thumb" />
<attr name="mccp_max" format="integer"></attr>
<attr name="mccp_start_angle" format="integer"></attr>
<attr name="mccp_end_angle" format="integer"></attr>
<attr name="mccp_seekbar_progress_unit_text" format="string"></attr>
<attr name="mccp_seekbar_progress_textsize" format="integer"></attr>
<attr name="mccp_seekbar_progress_unit_textsize" format="integer"></attr>
<attr name="mccp_seekbar_bg_width" format="dimension"></attr>
<attr name="mccp_seekbar_progress_width" format="dimension"></attr>
<attr name="mccp_seekbar_outside_color" format="color"></attr>
<attr name="mccp_seekbar_bg_color" format="color"></attr>
<attr name="mccp_seekbar_inside_color" format="color"></attr>
<attr name="mccp_seekbar_progress_bg_color" format="color"></attr>
<attr name="mccp_seekbar_thumb_color" format="color"></attr>
<attr name="mccp_seekbar_progress_text_color" format="color"></attr>
<attr name="mccp_seekbar_progress_unit_color" format="color"></attr>
<attr name="mccp_seekbar_progress_start_color" format="color"></attr>
<attr name="mccp_seekbar_progress_mid_color" format="color"></attr>
<attr name="mccp_seekbar_progress_end_color" format="color"></attr>
<attr name="mccp_seekbar_progress_linelong" format="dimension"></attr>
<attr name="mccp_seekbar_progress_thumb_r" format="dimension"></attr>
<attr name="mccp_seekbar_progress_color_style" format="integer"></attr>
</declare-styleable>
</resources>
5.创建一个color
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="text_color_user_group_sel_name">#FF0289ff</color>
<color name="text_color_user_group">#FF161616</color>
<color name="text_color_user_group_name">#FF161616</color>
<color name="text_color_main_valume">#FFe0e0e0</color>
<color name="text_color_high_set">#FF334456</color>
<color name="text_color_back">#FF0289ff</color>
<color name="mc_seekbar_outside_color">#FF2565c3</color>
<color name="mc_seekbar_bg_color">#FFbcb7b4</color>
<color name="mc_seekbar_inside_color">#FF88b6fb</color>
<color name="mc_seekbar_progress_bg_color">#FF0289ff</color>
<color name="mc_seekbar_thumb_color">#FFf6ff00</color>
<color name="text_color_mainvalume_t">#FF161616</color>
<color name="white">#FFFFFF</color>
</resources>
6.事件监听和功能调用
import android.media.AudioManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private AudioManager mAudioManager;
private MCCP_SeekBar VS_MainValume;
private int progress = 7;
private TextView tv_valume;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
VS_MainValume = (MCCP_SeekBar) findViewById(R.id.id_mcl_seekbar_main_valume);
tv_valume = (TextView)findViewById(R.id.id_b_valume);
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
//系统最大音量为15
VS_MainValume.setProgressMax(mAudioManager.getStreamMaxVolume(mAudioManager.STREAM_MUSIC));
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_SHOW_UI);
VS_MainValume.setProgress(progress);
tv_valume.setText(""+progress);
VS_MainValume.setOnMCLSeekBarChangeListener(new MCCP_SeekBar.OnMCCP_SeekBarChangeListener() {
@Override
public void onProgressChanged(MCCP_SeekBar mcSeekBar, int progress, boolean fromUser) {
MainActivity.this.progress = progress;
tv_valume.setText(""+progress);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_SHOW_UI);
}
});
}
//手机音量+-按钮监听
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (progress == 0) {
progress = 0;
return true;
}
--progress;
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_SHOW_UI);
tv_valume.setText(""+progress);
VS_MainValume.setProgress(progress);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
if (progress == 15) {
progress = 15;
return true;
}
++progress;
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_SHOW_UI);
tv_valume.setText(""+progress);
VS_MainValume.setProgress(progress);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
8.最后,自定义的view类
package com.example.longshine.zname;
import android.annotation.SuppressLint;
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.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@SuppressLint("ClickableViewAccessibility")
public class MCCP_SeekBar extends View {
//private boolean DEBUG = true false ;
private boolean DEBUG = false;
private OnMCCP_SeekBarChangeListener mOnMCCP_SeekBarChangeListener;
//保存状态
private static final String STATE_PARENT = "parent";
private static final String STATE_ANGLE = "angle";
//圆环paint对象
private Paint mColorOutsideWheelPaint;//外环
private Paint mColorWheelPaint; //seekbar背景
private Paint mColorWheelProgresPaint;//滑过的seekbar
private Paint mColorInsideCirclePaint;//内圆
private Paint mColorThumbPaint;//内圆
private Paint mColorUnitPaint;//单位
private Paint mColorProgressPaint;//progress
//圆环的宽度
private int mColorWheelStrokeWidth = 10;
private int mColorWheelStrokeSBWidth = 30;
private RectF mColorWheelRectangle = new RectF();
//private float mTranslationOffset;
//thumb
private Drawable mThumbDrawable = null;
@SuppressWarnings("unused")
private int mThumbHeight = 0;
private int mThumbWidth = 0;
private int[] mThumbNormal = null;
private int[] mThumbPressed = null;
@SuppressWarnings("unused")
private float mThumbLeft = 0;
@SuppressWarnings("unused")
private float mThumbTop = 0;
@SuppressWarnings("unused")
private float[] Out_pointerPosition;
@SuppressWarnings("unused")
private float[] In_pointerPosition;
private float[] thumb_pointerPosition;
private int mSeekBarCenterX = 0;
private int mSeekBarCenterY = 0;
private float mSeekBarSizeH = 0;
private float mSeekBarArcRadius = 0; //外圆弧半径
private float mSeekBarOutsideRadius = 0;//外环半径
private float mSeekBarIntsideRadius = 0;//内环半径
private float mSeekBarThumbRadius = 0; //Thumb所在半径
@SuppressWarnings("unused")
private float mSeekBarRadius = 0;//seekbar半径
@SuppressWarnings("unused")
private int mlinelong = 0;//seekbar progress 上的线的长度
private int mthumbRadius = 0;//thumb半径
//private int mSeekBarInsideCircleRadius = 0;//seekbar内圆半径
private static float mSeekBarDegreeThreshold = 2;
private boolean bool_Max = false;//滑动方向最大边界
private boolean bool_Min = false;//滑动方向最小边界
private boolean bool_DrawDir = false;//滑动方向true:正向
private boolean bool_Drawing = false;//true:正在滑动
private float mCurDrawDegree = 0;//当前实际的手指所在的角度
private float mOldDrawDegree = 0;//当前实际的手指所在的角度
//private float mCanDrawDegreeRight = 0;//能向右滑行的角度
private float mCanDrawDegreeLeft = 0;//能向左滑行的角度
private float mSeekBarDegree = 0;//进行绘制seekbar progress刻度的角度
private float mSeekBarStartDegree = 0;//起始角度
private float mSeekBarProgressStartDegree = 0;//起始角度
//private float mSeekBarStopDegree = 0;//结束角度
@SuppressWarnings("unused")
private float mSeekBarMax360 = 0;//起始角度
private float mSeekBarMaxDegree = 0;
private int mCurrentProgress = 0;
private int mSeekBarMax = 100;
private float mDegree = (float) 4.5;
@SuppressWarnings("unused")
private Bitmap bitmapOrg, resizedBitmap;
@SuppressWarnings("unused")
private int thumbwidth = 0;
@SuppressWarnings("unused")
private int thumbheight = 0;
@SuppressWarnings("unused")
private Matrix matrix;
//private boolean DEBUG=false;
private float seekbar_outside_width = 0;
//颜色
private int seekbar_outside_color;
private int seekbar_bg_color;
private int seekbar_inside_color;
private int seekbar_progress_bg_color;
private int seekbar_thumb_color;
//private Bitmap pointerBitmap;
//private Bitmap pointerBitmapShow;
/*
* 1:单一种颜色
* 2:单一种设定的渐变色
*/
@SuppressWarnings("unused")
private int seekbar_progress_color_style = 0;
private int seekbar_progress_text_color;
private int seekbar_progress_unit_color;
@SuppressWarnings("unused")
private int seekbar_progress_start_color;
@SuppressWarnings("unused")
private int seekbar_progress_mid_color;
@SuppressWarnings("unused")
private int seekbar_progress_end_color;
@SuppressWarnings("unused")
private int color_default;
//显示字体单位和大小
@SuppressWarnings("unused")
private String progress_unit_text = "dB";
private int progress_textsize = 0;
private int progress_unit_textsize = 0;
@SuppressWarnings("unused")
private String text_seekbar_progress = "0";
private int conversion = 0;
private SweepGradient s;
// 左下角开始
private int start_arc = 135;
private int end_wheel;
private Context mContext = null;
public MCCP_SeekBar(Context context) {
super(context);
mContext = context;
init(null, 0);
}
public MCCP_SeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init(attrs, 0);
}
public MCCP_SeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
final TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.MCCP_SeekBar, defStyle, 0);
initAttributes(a);
a.recycle();
// mAngle = (float) (-Math.PI / 2);
//外环
mColorOutsideWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorOutsideWheelPaint.setShader(s);
mColorOutsideWheelPaint.setColor(seekbar_outside_color);
mColorOutsideWheelPaint.setStyle(Paint.Style.STROKE);
mColorOutsideWheelPaint.setStrokeWidth(seekbar_outside_width);
//seekbar 背景
mColorWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorWheelPaint.setShader(s);
mColorWheelPaint.setColor(seekbar_bg_color);
mColorWheelPaint.setStyle(Paint.Style.STROKE);
mColorWheelPaint.setStrokeWidth(mColorWheelStrokeWidth);
//seekbar Progress
mColorWheelProgresPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorWheelProgresPaint.setShader(s);
mColorWheelProgresPaint.setColor(seekbar_progress_bg_color);
mColorWheelProgresPaint.setStyle(Paint.Style.STROKE);
mColorWheelProgresPaint.setStrokeWidth(mColorWheelStrokeSBWidth);
//内圆
mColorInsideCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorInsideCirclePaint.setShader(s);
mColorInsideCirclePaint.setColor(seekbar_inside_color);
//Thumb
mColorThumbPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorThumbPaint.setShader(s);
mColorThumbPaint.setColor(seekbar_progress_bg_color);
//mColorThumbPaint.setStyle(Paint.Style.STROKE);
mColorThumbPaint.setStrokeWidth(mColorWheelStrokeSBWidth / 2);
//mColorThumbPaint.setColor(seekbar_thumb_color);
//Text 单位
mColorUnitPaint = new Paint();
mColorUnitPaint.setColor(seekbar_progress_unit_color);
mColorUnitPaint.setTextSize(progress_unit_textsize);
//Text progress
mColorProgressPaint = new Paint();
mColorProgressPaint.setColor(seekbar_progress_text_color);
mColorProgressPaint.setTextSize(progress_textsize);
// 游标所在图片
// pointerBitmap = BitmapFactory.decodeResource(this.getResources(),
// R.drawable.main_valume_button);
bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.main_valume_button);//thrmb_nornal mccp_thumb
thumbwidth = bitmapOrg.getWidth();
thumbheight = bitmapOrg.getHeight();
invalidate();
}
private void initAttributes(TypedArray a) {
mSeekBarMax = a.getInteger(R.styleable.MCCP_SeekBar_mccp_max, 100);
if (mSeekBarMax == 46) {
mDegree = (float) 5.8;
}
//seekbar的起始角度和结束角度
start_arc = a.getInteger(R.styleable.MCCP_SeekBar_mccp_start_angle, 0);
//start_arc += 5;
end_wheel = a.getInteger(R.styleable.MCCP_SeekBar_mccp_end_angle, 360);
//mSeekBarMaxDegree = end_wheel;
mSeekBarMaxDegree = end_wheel - start_arc;
if (mSeekBarMaxDegree < 0) {
mSeekBarMaxDegree += 360;
}
mSeekBarDegree = (mCurrentProgress * mSeekBarMaxDegree / mSeekBarMax);
mDegree = mSeekBarMaxDegree / mSeekBarMax;
//环形大小设置
mColorWheelStrokeWidth = (int) a.getDimension(R.styleable.MCCP_SeekBar_mccp_seekbar_bg_width, 6);
mColorWheelStrokeSBWidth = (int) a.getDimension(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_width, 12);
//颜色设置
seekbar_outside_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_outside_color, Color.BLUE);
seekbar_bg_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_bg_color, Color.GRAY);
seekbar_inside_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_inside_color, Color.WHITE);
seekbar_progress_bg_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_bg_color, Color.GREEN);
seekbar_thumb_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_thumb_color, Color.YELLOW);
seekbar_progress_color_style = a.getInteger(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_color_style, 1);
seekbar_progress_text_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_text_color, Color.YELLOW);
seekbar_progress_unit_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_unit_color, Color.BLACK);
seekbar_progress_start_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_start_color, Color.YELLOW);
seekbar_progress_mid_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_mid_color, Color.GREEN);
seekbar_progress_end_color = a.getColor(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_end_color, Color.BLACK);
//color_default = getResources().getColor(R.color.mccp_color_default);
/*thumb*/
mThumbDrawable = a.getDrawable(R.styleable.MCCP_SeekBar_android_thumb);
mThumbWidth = this.mThumbDrawable.getIntrinsicWidth();
mThumbHeight = this.mThumbDrawable.getIntrinsicHeight();
mThumbNormal = new int[]{-android.R.attr.state_focused, -android.R.attr.state_pressed,
-android.R.attr.state_selected, -android.R.attr.state_checked};
mThumbPressed = new int[]{android.R.attr.state_focused, android.R.attr.state_pressed,
android.R.attr.state_selected, android.R.attr.state_checked};
seekbar_outside_width = mThumbWidth / 2;
//显示字体单位和大小
progress_unit_text = a.getString(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_unit_text);
progress_textsize = a.getInteger(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_textsize, 100);
progress_unit_textsize = a.getInteger(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_unit_textsize, 50);
text_seekbar_progress = String.valueOf(mCurrentProgress);
mlinelong = (int) a.getDimension(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_linelong, 30);
//mthumbRadius=(int) a.getDimension(R.styleable.MCCP_SeekBar_mccp_seekbar_progress_thumb_r, 10);
mthumbRadius = mColorWheelStrokeSBWidth / 2;
}
@SuppressLint("NewApi")
@Override
protected void onDraw(Canvas canvas) {
//外环
//canvas.drawCircle(mSeekBarCenterX, mSeekBarCenterY, mSeekBarOutsideRadius, mColorOutsideWheelPaint);
//内圆
//canvas.drawCircle(mSeekBarCenterX, mSeekBarCenterY, mSeekBarIntsideRadius, mColorInsideCirclePaint);
//seekbar背景
canvas.drawArc(mColorWheelRectangle, start_arc, 360, false, mColorWheelPaint);
//seekbar Progress
canvas.drawArc(mColorWheelRectangle, start_arc, (mDegree * mCurrentProgress), false, mColorWheelProgresPaint);
// //画背景图
//
// canvas.drawBitmap(pointerBitmapShow, mSeekBarCenterX-mSeekBarOutsideRadius, mSeekBarCenterX-mSeekBarOutsideRadius, null);
// //seekbar
drawThumb(canvas);
canvas.translate(mSeekBarCenterX, mSeekBarCenterY);
// //画背Thumb
drawThumbBitmap(canvas);
}
private void drawThumb(Canvas canvas) {
thumb_pointerPosition = calculatePointerPosition((360 - (start_arc - 90) - (mSeekBarMaxDegree / mSeekBarMax) * mCurrentProgress),
mSeekBarThumbRadius + mthumbRadius);
setThumbPosition(Math.toRadians((start_arc + (mSeekBarMaxDegree / mSeekBarMax) * mCurrentProgress)));
this.mThumbDrawable.setBounds((int) mThumbLeft, (int) mThumbTop, (int) (mThumbLeft + mThumbWidth), (int) (mThumbTop + mThumbHeight));
this.mThumbDrawable.draw(canvas);
}
private void setThumbPosition(double radian) {
double x = mSeekBarCenterX + mSeekBarRadius * Math.cos(radian);
double y = mSeekBarCenterY + mSeekBarRadius * Math.sin(radian);
mThumbLeft = (float) (x - mThumbWidth / 2);
mThumbTop = (float) (y - mThumbHeight / 2);
}
public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
double newHeight) {
// 获取这个图片的宽和高
float width = bgimage.getWidth();
float height = bgimage.getHeight();
// 创建操作图片用的matrix对象
Matrix matrix = new Matrix();
// 计算宽高缩放率
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 缩放图片动作
matrix.postScale(scaleWidth, scaleHeight);
Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
(int) height, matrix, true);
return bitmap;
}
// private void drawThumbBitmapButton(Canvas canvas) {
// //thumb_pointerPosition=calculatePointerPosition(45+(mSeekBarMax-mCurrentProgress)*mDegree, mSeekBaroutsideRadius+mthumbRadius);
// //canvas.drawCircle(thumb_pointerPosition[0], thumb_pointerPosition[1], mthumbRadius, mColorInsideCirclePaint);
//
// float angle = 0;
// //创建操作图片用的matrix对象
// matrix = new Matrix();
// //旋转图片动作
// if(mCurrentProgress<=mSeekBarMax/2){
// angle = (float) (225+mCurrentProgress*mDegree);
// }else {
// angle = (float) ((float) (mCurrentProgress - mSeekBarMax/2)*mDegree);
// }
// //matrix.postRotate(angle);
// resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, thumbwidth, thumbheight, matrix, true);
// canvas.drawBitmap(resizedBitmap, 0, mThumbTop, null);
//
// }
//计算角度,半径,圆的坐标
private float[] calculatePointerPosition(float angle, float Radius) {
float x, y;
x = (float) Math.sin(2 * Math.PI / 360 * angle) * Radius;
y = (float) Math.cos(2 * Math.PI / 360 * angle) * Radius;
//System.out.println("angle x:"+x+",y:"+y);
return new float[]{x, y};
}
//画thumb
private void drawThumbBitmap(Canvas canvas) {//(mSeekBarMaxDegree/mSeekBarMax)*mCurrentProgress)
// thumb_pointerPosition=calculatePointerPosition((360-(start_arc-90)-(mSeekBarMaxDegree/mSeekBarMax)*mCurrentProgress),
// mSeekBarThumbRadius+mthumbRadius);
// canvas.drawCircle(thumb_pointerPosition[0], thumb_pointerPosition[1], mthumbRadius, mColorThumbPaint);
thumb_pointerPosition = calculatePointerPosition(360 - (start_arc - 90),
mSeekBarArcRadius);
if (mCurrentProgress != 0) {
canvas.drawCircle(thumb_pointerPosition[0], thumb_pointerPosition[1], mthumbRadius, mColorThumbPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int min = Math.min(width, height);
setMeasuredDimension(min, min);
mSeekBarCenterX = min / 2;
mSeekBarCenterY = min / 2;
mSeekBarSizeH = height / 2;
//各圆的半径
mSeekBarArcRadius = mSeekBarSizeH - mThumbWidth; //外圆弧半径
mSeekBarRadius = mSeekBarArcRadius;
mSeekBarOutsideRadius = mSeekBarArcRadius - mSeekBarArcRadius / 7;//外环半径
mSeekBarIntsideRadius = mSeekBarOutsideRadius - mSeekBarOutsideRadius / 15;//内环半径
mSeekBarThumbRadius = mSeekBarIntsideRadius - mSeekBarIntsideRadius / 5; //Thumb所在半径
// System.out.println("MCL +mSeekBarCenterX:"+mSeekBarCenterX);
// System.out.println("MCL +mSeekBarCenterY:"+mSeekBarCenterY);
// System.out.println("MCL +mSeekBarSizeH:"+mSeekBarSizeH);
// System.out.println("MCL +mSeekBarArcRadius:"+mSeekBarArcRadius);
// System.out.println("MCL +mSeekBarOutsideRadius:"+mSeekBarOutsideRadius);
// System.out.println("MCL +mSeekBarIntsideRadius:"+mSeekBarIntsideRadius);
mColorWheelRectangle.set(mSeekBarCenterX - mSeekBarArcRadius, mSeekBarCenterX - mSeekBarArcRadius,
mSeekBarCenterX + mSeekBarArcRadius, mSeekBarCenterX + mSeekBarArcRadius);
// pointerBitmapShow=zoomImage(pointerBitmap,mSeekBarOutsideRadius*2,mSeekBarOutsideRadius*2);
}
public int getValue() {
return conversion;
}
private void SeekTo() {
float drawDegree = 0;
if (bool_DrawDir == true) {//正向,变大
bool_Min = false;
if (mOldDrawDegree > mCurDrawDegree) {
if (DEBUG) System.out.println("MCL +mOldDrawDegree:" + mOldDrawDegree);
if (DEBUG) System.out.println("MCL +mCurDrawDegree:" + mCurDrawDegree);
if ((360 >= mOldDrawDegree) && (mOldDrawDegree >= 225) && (135 >= mCurDrawDegree) && (mCurDrawDegree >= 0)) {
//在临界点切过,方向不变
bool_DrawDir = true;
} else {
bool_DrawDir = false;
mSeekBarStartDegree = mOldDrawDegree;
mSeekBarProgressStartDegree = mCurrentProgress * mDegree;
mCanDrawDegreeLeft = mCurrentProgress * mDegree;
mSeekBarMax360 = mSeekBarStartDegree + mSeekBarMaxDegree - 360;
if (DEBUG) System.out.println("MCL +bool_DrawDir:" + bool_DrawDir);
return;
}
}
//到达最大边界
if (bool_Max == true) {
mOldDrawDegree = mCurDrawDegree;
return;
}
if (mCurDrawDegree >= mSeekBarStartDegree) {
drawDegree = mCurDrawDegree - mSeekBarStartDegree + mSeekBarDegreeThreshold;
} else if (mCurDrawDegree < mSeekBarStartDegree) {
drawDegree = mCurDrawDegree + (360 - mSeekBarStartDegree) + mSeekBarDegreeThreshold;
}
//用于计算mCurrentProgress
mSeekBarDegree = mSeekBarProgressStartDegree + drawDegree;
if (DEBUG) System.out.println("MCL +mSeekBarDegree:" + mSeekBarDegree);
if (DEBUG) System.out.println("MCL +mCurrentProgress:" + mCurrentProgress);
//System.out.println("MCL +mSeekBarProgressStartDegree:"+mSeekBarProgressStartDegree);
if ((mSeekBarDegree > mSeekBarMaxDegree) || (0 > mSeekBarDegree)) {
mSeekBarDegree = mSeekBarMaxDegree;
bool_Max = true;
}
if ((mSeekBarDegree >= 0) && (mSeekBarDegree <= mSeekBarMaxDegree)) {//正常的大半圆
mCurrentProgress = (int) (mSeekBarMax * mSeekBarDegree / mSeekBarMaxDegree);
}
//用于在正向中反向滑动
mOldDrawDegree = mCurDrawDegree;
if (DEBUG) System.out.println("MCL +++++++++");
} else if (bool_DrawDir == false) {//反向,变小
bool_Max = false;
if (mOldDrawDegree < mCurDrawDegree) {
if (DEBUG) System.out.println("MCL -mOldDrawDegree:" + mOldDrawDegree);
if (DEBUG) System.out.println("MCL -mCurDrawDegree:" + mCurDrawDegree);
if ((360 >= mCurDrawDegree) && (mCurDrawDegree >= 225) && (135 >= mOldDrawDegree) && (mOldDrawDegree >= 0)) {
//在临界点切过,方向不变
bool_DrawDir = false;
} else {
bool_DrawDir = true;
mSeekBarStartDegree = mOldDrawDegree;
mSeekBarProgressStartDegree = mCurrentProgress * mDegree;
mCanDrawDegreeLeft = mCurrentProgress * mDegree;
mSeekBarMax360 = mSeekBarStartDegree + mSeekBarMaxDegree - 360;
if (DEBUG) System.out.println("MCL -bool_DrawDir:" + bool_DrawDir);
return;
}
}
//到达最小边界
if (bool_Min == true) {
mOldDrawDegree = mCurDrawDegree;
return;
}
if (mCurrentProgress == 0) {
bool_Min = true;
mOldDrawDegree = mCurDrawDegree;
return;
}
if (mSeekBarStartDegree >= mCurDrawDegree) {
drawDegree = mSeekBarStartDegree - mCurDrawDegree - mSeekBarDegreeThreshold;
} else if (mSeekBarStartDegree < mCurDrawDegree) {
drawDegree = mSeekBarStartDegree + (360 - mCurDrawDegree) - mSeekBarDegreeThreshold;
}
if (DEBUG) System.out.println("MCL -drawDegree:" + drawDegree);
if (drawDegree >= mCanDrawDegreeLeft) {
bool_Min = true;
mSeekBarDegree = 0;
//System.out.println("MCL X");
} else {
mSeekBarDegree = mSeekBarProgressStartDegree - drawDegree;
if (mSeekBarDegree > 360) {
mSeekBarDegree = mSeekBarDegree - 360;
}
}
//用于在反向中正向滑动
mOldDrawDegree = mCurDrawDegree;
if ((mSeekBarDegree >= 0) && (mSeekBarDegree <= mSeekBarMaxDegree)) {//正常的大半圆
mCurrentProgress = (int) (mSeekBarMax * mSeekBarDegree / mSeekBarMaxDegree);
}
if (DEBUG) System.out.println("MCL -------------------------------------------");
//System.out.println("MCL -mCanDrawDegreeLeft:"+mCanDrawDegreeLeft);
if (DEBUG) System.out.println("MCL -mSeekBarMaxDegree:" + mSeekBarMaxDegree);
if (DEBUG) System.out.println("MCL -mSeekBarDegree:" + mSeekBarDegree);
//System.out.println("MCL -mSeekBarProgressStartDegree:"+mSeekBarProgressStartDegree);
if (DEBUG) System.out.println("MCL ---------");
}
//System.out.println("MCL -mCurrentProgress:"+mCurrentProgress);
if (mOnMCCP_SeekBarChangeListener != null) {
mOnMCCP_SeekBarChangeListener.onProgressChanged(this, mCurrentProgress, true);
}
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//System.out.println("onTouchEvent x:"+x+",y:"+y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mThumbDrawable.setState(mThumbPressed);
mSeekBarStartDegree = GetDegree(x, y);
mSeekBarProgressStartDegree = mCurrentProgress * mDegree;
mCanDrawDegreeLeft = mCurrentProgress * mDegree;
mSeekBarMax360 = mSeekBarStartDegree + mSeekBarMaxDegree - 360;
mOldDrawDegree = mSeekBarStartDegree;
bool_Drawing = false;
if (DEBUG) System.out.println("MCL d mSeekBarStartDegree:" + mSeekBarStartDegree);
if (DEBUG) System.out.println("MCL d mCurDrawDegree:" + mCurDrawDegree);
if (DEBUG) System.out.println("MCL ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
mThumbDrawable.setState(mThumbPressed);
mCurDrawDegree = GetDegree(x, y);
if (DEBUG) System.out.println("MCL mCurDrawDegree:" + mCurDrawDegree);
if (bool_Drawing == false) {
bool_Drawing = true;
if (mCurDrawDegree >= mSeekBarStartDegree + mSeekBarDegreeThreshold) {
if ((360 >= mCurDrawDegree) && (mCurDrawDegree >= 225) &&
(135 >= mSeekBarStartDegree + mSeekBarDegreeThreshold)
&& (mSeekBarStartDegree + mSeekBarDegreeThreshold >= 0)) {
bool_DrawDir = false;//反向,变小
} else {
bool_DrawDir = true;//正向,变大
}
} else if (mCurDrawDegree < mSeekBarStartDegree - mSeekBarDegreeThreshold) {
if ((360 >= mSeekBarStartDegree - mSeekBarDegreeThreshold) &&
(mSeekBarStartDegree - mSeekBarDegreeThreshold >= 225)
&& (135 >= mCurDrawDegree) && (mCurDrawDegree >= 0)) {
bool_DrawDir = true;//正向,变大
} else {
bool_DrawDir = false;//反向,变小
}
}
if (DEBUG) System.out.println("MCL MOVE bool_DrawDir:" + bool_DrawDir);
} else if (bool_Drawing == true) {
SeekTo();
}
break;
case MotionEvent.ACTION_UP:
bool_Drawing = false;
mThumbDrawable.setState(mThumbNormal);
invalidate();
break;
default:
bool_Drawing = false;
mThumbDrawable.setState(mThumbNormal);
invalidate();
break;
}
if (event.getAction() == MotionEvent.ACTION_MOVE && getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(true);
}
return true;
}
private float GetDegree(float x, float y) {
float Degree = 0;
double radian = Math.atan2(y - mSeekBarCenterY, x - mSeekBarCenterX);
if (radian < 0) {
radian = radian + 2 * Math.PI;
}
Degree = Math.round(Math.toDegrees(radian));
return Degree;
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
Bundle state = new Bundle();
state.putParcelable(STATE_PARENT, superState);
state.putFloat(STATE_ANGLE, mCurrentProgress);
return state;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Bundle savedState = (Bundle) state;
Parcelable superState = savedState.getParcelable(STATE_PARENT);
super.onRestoreInstanceState(superState);
mCurrentProgress = (int) savedState.getFloat(STATE_ANGLE);
mSeekBarDegree = (mCurrentProgress * mSeekBarMaxDegree / mSeekBarMax);
// if(mCurrentProgress==mSeekBarMax){
// text_seekbar_progress=String.valueOf(mSeekBarMax-mCurrentProgress);
// }else{
// text_seekbar_progress=String.valueOf(0-(mSeekBarMax-mCurrentProgress));
// }
text_seekbar_progress = String.valueOf(mCurrentProgress);
}
public void setOnMCLSeekBarChangeListener(OnMCCP_SeekBarChangeListener l) {
mOnMCCP_SeekBarChangeListener = l;
}
public interface OnMCCP_SeekBarChangeListener {
public abstract void onProgressChanged(MCCP_SeekBar mcSeekBar,
int progress, boolean fromUser);
}
public void setProgressThumb(int thumbId) {
mThumbDrawable = mContext.getResources().getDrawable(thumbId);
}
public void setProgressMax(int max) {
mSeekBarMax = max;
mDegree = mSeekBarMaxDegree / mSeekBarMax;
}
/*
* 增加set方法,用于在java代码中调用
*/
public void setProgress(int progress) {
if (progress > mSeekBarMax) {
progress = mSeekBarMax;
}
if (progress < 0) {
progress = 0;
}
mCurrentProgress = progress;
//if (mOnMCCP_SeekBarChangeListener != null){
// mOnMCCP_SeekBarChangeListener.onProgressChanged(this,mCurrentProgress, true);
//}
// mSeekBarDegree = (progress * mSeekBarMaxDegree / mSeekBarMax);
// if(mCurrentProgress==mSeekBarMax){
// text_seekbar_progress=String.valueOf(mSeekBarMax-mCurrentProgress);
// }else{
// text_seekbar_progress=String.valueOf(0-(mSeekBarMax-mCurrentProgress));
// }
//text_seekbar_progress=String.valueOf(mCurrentProgress);
//System.out.println("MCL setProgress:"+mCurrentProgress);
invalidate();
}
/*
* 增加setCanTouch方法,用于在java代码中调用
*/
public void setTouch(boolean touch) {
//CanTouch=touch;
}
/*
* 增加setCanTouch方法,用于在java代码中调用
*/
public int getProgress() {
return mCurrentProgress;
}
}