您的位置:首页 > 其它

一个半圆形拖动条

2016-01-06 16:45 211 查看
请标注原文链接地址:http://write.blog.csdn.net/postedit/50470134





pulic class Rota_CircleView extends View {

private Paint paint;

private float a=330f,b=330f;

private float cx=370f,cy=470f;

private float track_radius = 100f; //圆弧半径

private int width;

private double mAngleDeg=0; //角度 相对 startAngle 的 角度

private Bitmap mThumbBitmap;

private double mAngleRad = 1; //当前角度对应的弧度

private double startAngleDeg=30f; //起点与水平方向的夹角

private double totalAngleDeg = 180;

private boolean mEnable = true;

private float mPercent = 0; //百分比

public interface OnCircleViewChangeListener {//圆弧拖动时候回调接口,包括拖动弧度所占百分比,停止拖动时候所占百分比

void onStopTouch(float percent);

void onMoveTouch(float percent);

}

private OnCircleViewChangeListener mOnCircleViewChangeListener;

public void setOnCircleViewChangeListener(OnCircleViewChangeListener l) {

mOnCircleViewChangeListener = l;

}

public Rota_CircleView(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public Rota_CircleView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

// TODO Auto-generated constructor stub

getAttrs(context, attrs);

}

public Rota_CircleView(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

getAttrs(context, attrs);

}

/**

* 得到属性值

*

* @param context

* @param attrs

*/

private void getAttrs(Context context, AttributeSet attrs) {

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Rota_CircleView);

track_radius = ta.getDimension(R.styleable.Rota_CircleView_track_radius, 100f);

int bmp_id = ta.getResourceId(R.styleable.Rota_CircleView_dot_bmp, R.drawable.scrubber_control_normal_holo);

ta.recycle();

mThumbBitmap = BitmapFactory.decodeResource(getResources(), bmp_id);

totalAngleDeg = 180 + 2 * startAngleDeg;

DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();

Log.i("tzc","track_radius = " + track_radius+", dm.densityDpi = " + dm.densityDpi);

}

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

getParent().requestDisallowInterceptTouchEvent(true);

return super.dispatchTouchEvent(event);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (!mEnable)

return false;

// TODO Auto-generated method stub

switch (event.getAction()) {

case MotionEvent.ACTION_MOVE:

float newx=event.getX();

float newy=event.getY();

pointxy xy = touchToPoint(newx, newy);

cx = xy.x;

cy = xy.y;

if(mOnCircleViewChangeListener != null) {

mOnCircleViewChangeListener.onMoveTouch(mPercent);

}

invalidate();

break;

case MotionEvent.ACTION_UP:

if(mOnCircleViewChangeListener != null) {

mOnCircleViewChangeListener.onStopTouch(mPercent);

}

break;

default:

break;

}

return true;

}

/*

* 由触摸点坐标 获得 相对 startAngle 的角度

*/

private double pointToAngle(float newx, float newy) {

double angle = 0; //角度 相对 startAngle 的 角度

double degrees = 0; //角度

float y = b - newy;

if (x > 0 && y > 0) {

x = newx - a;

y = b - newy;

mAngleRad = Math.atan(x / y);

degrees = mAngleRad*180/Math.PI;

angle = startAngleDeg + 90 + degrees;

} else if (x > 0 && y < 0) {

x = newx - a;

y = newy - b;

mAngleRad = Math.atan(x / y);

degrees = mAngleRad*180/Math.PI;

angle = startAngleDeg + 270 - degrees;

} else if (x < 0 && y < 0) {

x = a - newx;

y = newy - b;

mAngleRad = Math.atan(x / y);

degrees = mAngleRad*180/Math.PI;

angle = startAngleDeg - 90 + degrees;

} else if (x < 0 && y > 0) {

x = a - newx;

y = b - newy;

mAngleRad = Math.atan(x / y);

degrees = mAngleRad*180/Math.PI;

angle = startAngleDeg + 90 - degrees;

}

return angle;

}

private pointxy touchToPoint(float newx, float newy) {

pointxy xy = new pointxy(0, 0);

mAngleDeg = pointToAngle(newx, newy);

mPercent = (float) (mAngleDeg/totalAngleDeg);

Log.i("tzc", "angle1 = " + mAngleDeg );

if(mAngleDeg <=0.0)

mAngleDeg = 360 + mAngleDeg;

if(mAngleDeg >= totalAngleDeg)

mAngleDeg = totalAngleDeg;

Log.i("tzc", "angle2 = " + mAngleDeg );

double x_sin = track_radius * Math.sin(mAngleRad);

double y_cos = track_radius * Math.cos(mAngleRad);

Log.i("tzc", "x_sin = " + x_sin + "y_cos = " + y_cos );

float x = newx - a;

float y = b - newy;

double x_2 = x_sin;

double y_2 = y_cos;

if (x > 0 && y > 0) {

} else if (x > 0 && y < 0) {

y_2 = -1*y_2;

} else if (x < 0 && y < 0) {

x_2 = -1*x_2;

y_2 = -1*y_2;

} else if (x < 0 && y > 0) {

x_2 = -1*x_2;

}

if( isLimit(x_2, y_2)) {

Log.i("tzc", "isLimit");

if(x_2 < 0) {

xy = angleToPoint(0);

} else {

xy = angleToPoint(totalAngleDeg);

}

} else {

if (x > 0 && y > 0) {

xy.x = (float) (a + x_sin);

xy.y = (float) (b - y_cos);

} else if (x > 0 && y < 0) {

xy.x = (float) (a + x_sin);

xy.y = (float) (b + y_cos);

} else if (x < 0 && y < 0) {

xy.x = (float) (a - x_sin);

xy.y = (float) (b + y_cos);

} else if (x < 0 && y > 0) {

xy.x = (float) (a - x_sin);

xy.y = (float) (b - y_cos);

}

}

return xy;

}

private class pointxy{

public float x;

public float y;

pointxy(float x, float y){

this.x = x;

this.y = y;

}

}

private boolean isLimit (double x_sin, double y_cos) {

boolean limit = false;

if(y_cos < 0) {

if(x_sin == 0) {

limit = true;

} else if(x_sin < 0){

if(x_sin > y_cos) {

limit = true;

}

} else {

if(x_sin < -1*y_cos) {

limit = true;

}

}

}

return limit;

}

public void setEnable(boolean enble) {

this.mEnable = enble;

}

private pointxy angleToPoint(double angle) {

pointxy xy = new pointxy(0, 0);

double angdeg1 = angle - startAngleDeg;

double angdeg = Math.abs(angdeg1);

double radians = Math.toRadians(angdeg);

float x = (float) (track_radius * Math.cos(radians));

float y = (float) (track_radius * Math.sin(radians));

if (angdeg1 <= 0f) {

xy.x = (float) (a - x);

xy.y = (float) (b + y);

} else {

xy.x = (float) (a - x);

xy.y = (float) (b - y);

}

return xy;

}

public void setThumbPos(float Percent) {

pointxy xy = new pointxy(0, 0);

mAngleDeg = totalAngleDeg * Percent;

xy = angleToPoint(mAngleDeg);

cx = xy.x;

cy = xy.y;

mPercent = Percent;

if(mOnCircleViewChangeListener != null) {

mOnCircleViewChangeListener.onMoveTouch(mPercent);

}

invalidate();

}

public void setThumbPos(float Percent) {

pointxy xy = new pointxy(0, 0);

mAngleDeg = totalAngleDeg * Percent;

xy = angleToPoint(mAngleDeg);

cx = xy.x;

cy = xy.y;

mPercent = Percent;

if(mOnCircleViewChangeListener != null) {

mOnCircleViewChangeListener.onMoveTouch(mPercent);

}

invalidate();

}

@SuppressLint("DrawAllocation")

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

//Log.i("tzc", "onDraw()");

if(mThumbBitmap != null) {

int h = mThumbBitmap.getHeight();

int w = mThumbBitmap.getWidth();

canvas.drawBitmap(mThumbBitmap, cx-w/2, cy-h/2, null);

}

paint = new Paint();

RectF rectF=new RectF(15,10,width-15,width-10);

paint.setStyle(Style.STROKE);

paint.setStrokeWidth(22);

paint.setAntiAlias(true);

SweepGradient shader=new SweepGradient(cx, cy, new int[]{0xFFE64506,0xFF1D2BF2,0xFF1D2BF0,Color.GREEN,Color.YELLOW,0xFFE64506,0xFFE64506},

new float[]{0,0.3f,0.5f,0.7f,0.8f,0.9f,1});

paint.setShader(shader);

canvas.drawArc(rectF, 150,(float)mAngleDeg,false, paint);

}

public void set_value(int value){

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = MeasureSpec.getSize(widthMeasureSpec);

a = width/2;

b = width/2;

//Log.i("tzc", "onMeasure()");

//cx=(float) (a-track_radius*Math.sin(radians));

//cy=(float) (b+track_radius*Math.cos(radians));

//invalidate();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: