此控件是一个开关组件
一个三项开关
可以滑动
可以点击
可以自定义背景颜色
费话少说
接下来是使用说明,(源码放在文章最后)
从布局开始
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/blue"
android:padding="20dp">
<com.z.proxy.androidtest.SwitchZ
android:id="@+id/switchz"
android:layout_width="120dp"
android:layout_height="40dp"
app:radian="25sp"
app:viewBgColor="#ffffff"
app:defaultCircleColor="#999999"
app:leftCircleColor="#Ea4a4a"
app:midCircleColor="#ffc600"
app:rightCircleColor="#239a1c"/>
</LinearLayout>
app:viewBgColor="#ffffff" app:defaultCircleColor="#999999" app:leftCircleColor="#Ea4a4a" app:midCircleColor="#ffc600" app:rightCircleColor="#239a1c"从上到下依次代表的意思:背景边角弧度,圆的默认颜色,左边圆选中的颜色,中间圆选中的颜色,右边圆选中的颜色
组件包含一个attrs文件,直接上传attrs的内容
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="switch_style">
<attr name="radian" format="dimension"/>
<attr name="viewBgColor" format="color"/>
<attr name="defaultCircleColor" format="color"/>
<attr name="leftCircleColor" format="color"/>
<attr name="midCircleColor" format="color"/>
<attr name="rightCircleColor" format="color"/>
</declare-styleable>
</resources>
然后就是牛逼的java代码了,(只是指java牛逼,我写的依然只能代表我是)
在外部调用的时候可以用/** * 三项开关 * Created by zhangxiaohui on 2017/3/17. */ public class SwitchZ extends View { private float viewWidth, viewHeight; private Paint bgPaint;//背景画笔 private Paint circlePaint;//中间圆画笔 private Paint textPaint;//写文字画笔 private Paint imagePaint;//中间图片画笔 private Paint moveCirclePaint;//移动效果画笔 private Paint arrowPaint;//箭头画笔 private int bgColor = Color.parseColor("#ffffff");//背景颜色 private int textColor = Color.parseColor("#ffffff");//字体颜色 private String arrowColor = "#e0e0e0";//默认箭头颜色 private int normalColor = Color.parseColor("#999999");//未选中颜色 private int leftSelectColor = Color.parseColor("#Ea4a4a");//左边选中颜色 private int rightSelectColor = Color.parseColor("#239a1c");//右边选中颜色 private int midSelectColor = Color.parseColor("#ffc600");//中间选中颜色 private int circleColor = normalColor;//记录颜色 private float circleRadian = 0f;//背景的弧度 private float showCircleX = 0f;//当前界面显示的圆坐标X private float showCircleY = 0f;//当前界面显示的圆坐标Y private float showCircleRadian = 0f;//当前界面显示的圆的半径 private float moveCircleX = 0f; private float moveCircleY = 0f; private float moveCircleRadian = 0f; private boolean isMove = false; private SWITCHBG switchbg = SWITCHBG.RIGHT; public SwitchZ(Context context) { this(context, null); } public SwitchZ(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.switch_style); circleRadian = a.getDimension(R.styleable.switch_style_radian, 70f); bgColor = a.getColor(R.styleable.switch_style_viewBgColor,Color.parseColor("#ffffff")); normalColor = a.getColor(R.styleable.switch_style_defaultCircleColor, Color.parseColor("#999999")); leftSelectColor = a.getColor(R.styleable.switch_style_leftCircleColor, Color.parseColor("#Ea4a4a")); midSelectColor = a.getColor(R.styleable.switch_style_midCircleColor, Color.parseColor("#ffc600")); rightSelectColor = a.getColor(R.styleable.switch_style_rightCircleColor, Color.parseColor("#239a1c")); a.recycle(); init(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e("onDraw", "onDraw"); RectF rectF = new RectF(0, 0, viewWidth, viewHeight); canvas.drawRoundRect(rectF, circleRadian, circleRadian, bgPaint); setDefaultCircleBackgroundColor(SWITCHBG.MID, canvas); setDefaultCircleBackgroundColor(SWITCHBG.LEFT, canvas); setDefaultCircleBackgroundColor(SWITCHBG.RIGHT, canvas); setCircleColor(switchbg); canvas.drawCircle(showCircleX, showCircleY, showCircleRadian, circlePaint);//默认选中圆上色 float leftArrowX = (float) (viewWidth / 2.0 - (viewWidth / 2.0 * 2.0 / 6.0)); float leftArrowY = viewHeight / 2 + circlePaint.getTextSize(); float rightArrowX = (float) (viewWidth / 2.0 + (viewWidth / 2.0 / 5.0)); float rightArrowY = leftArrowY; arrowPaint.setTextSize(viewHeight / 3);//arrowColor if(switchbg == SWITCHBG.LEFT){ arrowPaint.setColor(leftSelectColor); canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint); arrowPaint.setColor(Color.parseColor(arrowColor)); canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint); }else if(switchbg == SWITCHBG.RIGHT){ arrowPaint.setColor(rightSelectColor); canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint); arrowPaint.setColor(Color.parseColor(arrowColor)); canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint); }else { arrowPaint.setColor(Color.parseColor(arrowColor)); canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint); canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint); } if (isMove) { canvas.drawCircle(moveCircleX, moveCircleY, moveCircleRadian, moveCirclePaint);//移动的圆 } textPaint.setTextSize(viewHeight / 3); float leftTextX = viewWidth / 3 / 2 - textPaint.getTextSize() / 2; float leftTextY = viewHeight / 2 + textPaint.getTextSize() / 3; float rightTextX = viewWidth / 3 * 2 + (viewWidth - viewWidth / 3 * 2) / 2 - textPaint.getTextSize() / 2; float rightTextY = leftTextY; canvas.drawText("左", leftTextX, leftTextY, textPaint); canvas.drawText("右", rightTextX, rightTextY, textPaint); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.point_switch_m); float imgX = viewWidth / 2 - bitmap.getWidth() / 2;// imagePaint.getTextSize() / 2 float imgY = viewHeight / 2 - bitmap.getHeight() / 2; // int width = viewHeight / 3 * 2 / 3; canvas.drawBitmap(bitmap, imgX, imgY, imagePaint);//zoomImg(bitmap, width, width) } public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) { // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); return newbm; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.e("onMeasure", "onMeasure"); viewWidth = getMeasuredWidth(); viewHeight = getMeasuredHeight(); /**画圆初始赋值*/ setCircleColor(SWITCHBG.MID); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 设置非选中圆的默认背景 * * @param switchbg * @param canvas */ private void setDefaultCircleBackgroundColor(SWITCHBG switchbg, Canvas canvas) { if (this.switchbg == switchbg) { return; } circleColor = normalColor; circlePaint.setColor(circleColor); switch (switchbg) { case LEFT: setCircleSize(SWITCHBG.LEFT); break; case MID: setCircleSize(SWITCHBG.MID); break; case RIGHT: setCircleSize(SWITCHBG.RIGHT); break; } canvas.drawCircle(showCircleX, showCircleY, showCircleRadian, circlePaint);//中间圆 } private void setCircleColor(SWITCHBG switchbg) { switch (switchbg) { case LEFT: setCircleSize(SWITCHBG.LEFT); circleColor = leftSelectColor; break; case MID: setCircleSize(SWITCHBG.MID); circleColor = midSelectColor; break; case RIGHT: setCircleSize(SWITCHBG.RIGHT); circleColor = rightSelectColor; break; } circlePaint.setColor(circleColor); moveCirclePaint.setColor(circleColor); } /** * 设置圆大小及位置 * * @param switchbg */ private void setCircleSize(SWITCHBG switchbg) { switch (switchbg) { case LEFT: showCircleX = viewWidth / 3 / 2; showCircleY = viewHeight / 2; showCircleRadian = viewHeight / 3; break; case MID: float sideCircleCenter = viewHeight / 3; float midCircleCenter = sideCircleCenter * 2 / 3; showCircleX = viewWidth / 2; showCircleY = viewHeight / 2; showCircleRadian = midCircleCenter; break; case RIGHT: showCircleX = viewWidth / 3 * 2 + (viewWidth - (viewWidth / 3 * 2)) / 2; showCircleY = viewHeight / 2; showCircleRadian = viewHeight / 3; break; } } float downX; float downY; float upX; float upY; boolean outsideStart = false; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isMove = false; outsideStart = false; downX = event.getX(); downY = event.getY(); moveCircleY = viewHeight / 2; if (upX <= viewWidth / 3 && upX > 0 && upY <= viewHeight && upY > 0) { // moveCircleX = viewWidth / 3 / 2; moveCircleRadian = viewHeight / 3; } else if (upX > viewWidth / 3 && upX < viewWidth * 2 / 3 && upY > 0 && upY < viewHeight) { // moveCircleX = viewWidth / 2; moveCircleRadian = viewHeight / 3 * 2 / 3; } else if (upX > viewWidth * 2 / 3 && upX < viewWidth && upY > 0 && upY < viewHeight) { // moveCircleX = viewWidth - viewHeight / 2; moveCircleRadian = viewHeight / 3; } break; case MotionEvent.ACTION_MOVE: isMove = true; outsideStart = false; upX = event.getX(); upY = event.getY(); if (downX < (showCircleX - showCircleRadian) || downX > (showCircleX + showCircleRadian)) { outsideStart = true; return true; } moveCircleX = event.getX(); invalidate(); break; case MotionEvent.ACTION_UP: isMove = false; if (outsideStart) { return true; } upX = event.getX(); upY = event.getY(); outsideStart = false; if (upX <= viewWidth / 3 && upY <= viewHeight && upY > 0) {//左 showCircleX = viewWidth / 3 / 2; showCircleY = viewHeight / 2; showCircleRadian = viewHeight / 3; switchbg = SWITCHBG.LEFT; if (switchScrollListner != null) { switchScrollListner.leftListner(); } } else if (upX > viewWidth / 3 && upX < viewWidth * 2 / 3 && upY > 0 && upY < viewHeight) {//中 showCircleX = viewWidth / 2; showCircleY = viewHeight / 2; showCircleRadian = viewHeight / 3 * 2 / 3; switchbg = SWITCHBG.MID; if (switchScrollListner != null) { switchScrollListner.midListner(); } } else if (upX > viewWidth * 2 / 3 && upX < viewWidth * 2 && upY > 0 && upY < viewHeight) {//右 showCircleX = viewWidth / 3 * 2 + (viewWidth - (viewWidth / 3 * 2)) / 2; showCircleY = viewHeight / 2; showCircleRadian = viewHeight / 3; switchbg = SWITCHBG.RIGHT; if (switchScrollListner != null) { switchScrollListner.rightListner(); } } invalidate(); break; } return true; } private void init() { bgPaint = new Paint(); bgPaint.setColor(bgColor); bgPaint.setStyle(Paint.Style.FILL); bgPaint.setAntiAlias(true); circlePaint = new Paint(); circlePaint.setColor(circleColor); circlePaint.setAntiAlias(true); moveCirclePaint = new Paint(); moveCirclePaint.setColor(circleColor); moveCirclePaint.setStyle(Paint.Style.FILL); moveCirclePaint.setAntiAlias(true); arrowPaint = new Paint(); arrowPaint.setColor(circleColor); arrowPaint.setStyle(Paint.Style.FILL); Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); arrowPaint.setTypeface(font); arrowPaint.setAntiAlias(true); textPaint = new Paint(); textPaint.setColor(textColor); textPaint.setStyle(Paint.Style.FILL); textPaint.setStrokeWidth(1f); textPaint.setAntiAlias(true); imagePaint = new Paint(); imagePaint.setStyle(Paint.Style.FILL); imagePaint.setStrokeWidth(1f); imagePaint.setAntiAlias(true); } /** * 设置默认选中值 * @param switchbg */ public void switchLeftOn(SWITCHBG switchbg) { this.switchbg = switchbg; } /** * 更新开关状态 * @param switchbg */ public void updateSwitchState(SWITCHBG switchbg){ this.switchbg = switchbg; invalidate(); } public enum SWITCHBG { LEFT, MID, RIGHT } /** * 三个点击事件回调 */ public interface SwitchScrollListner { void leftListner(); void midListner(); void rightListner(); } SwitchScrollListner switchScrollListner; public void setSwitchScrollListner(SwitchScrollListner switchScrollListner) { this.switchScrollListner = switchScrollListner; } }
来进行自定义操作SwitchScrollListner
欢迎各位童鞋提出宝贵意见