Android 自定义可选择范围的控件
2016-05-12 11:37
288 查看
刚研究自定义控件不久,见别人问怎么写一个可选择范围的控件。就自己简单的写了一个。
要实现的效果如图:
![](http://img.blog.csdn.net/20160512114204478?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
代码:
![](http://img.blog.csdn.net/20160512120307720?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
要实现的效果如图:
代码:
package com.elink.tianyu.cardslistview.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.elink.tianyu.cardslistview.R; /** * 选择范围控件 * Created by zty on 2016/5/12. */ public class RangeSelectionView extends View { private Paint paintBackground;//背景线的画笔 private Paint paintCircle;//起始点圆环的画笔 private Paint paintWhileCircle;//起始点内圈白色区域的画笔 private Paint paintText;//起始点数值的画笔 private Paint paintConnectLine;//起始点连接线的画笔 private int height = 0;//控件的高度 private int width = 0;//控件的宽度 private float centerVertical = 0;//y轴的中间位置 private float backlineWidth = 5;//底线的宽度 private float marginhorizontal = 35;//横向边距 private float marginTop = 50;//文字距顶部的距离 private float pointStart = 0;//起点的X轴位置 private float pointEnd = 0;//始点的Y轴位置 private float circleRadius = 30;//起始点圆环的半径 private float numStart = 0;//数值的开始值 private float numEnd = 0;//数值的结束值 private int textSize = 30;//文字的大小 private String strUnit = "¥";//刻度的单位 private boolean isRunning = false;//是否可以滑动 private boolean isStart = true;//起点还是终点 true:起点;false:终点。 public RangeSelectionView(Context context) { super(context); init(); } public RangeSelectionView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RangeSelectionView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取控件的宽高、中线位置、起始点、起始数值 height = MeasureSpec.getSize(heightMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); centerVertical = height / 2; pointStart = marginhorizontal; pointEnd = width - marginhorizontal; numStart = getProgressNum(pointStart); numEnd = getProgressNum(pointEnd); } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //如果点击的点在第一个圆内就是起点,并且可以滑动 if (event.getX() >= (pointStart - circleRadius) && event.getX() <= (pointStart + circleRadius)) { isRunning = true; isStart = true; pointStart = event.getX(); //如果点击的点在第二个圆内就是终点,并且可以滑动 } else if (event.getX() <= (pointEnd + circleRadius) && event.getX() >= (pointEnd - circleRadius)) { isRunning = true; isStart = false; pointEnd = event.getX(); } else { //如果触控点不在圆环内,则不能滑动 isRunning = false; } break; case MotionEvent.ACTION_MOVE: if (isRunning) { if (isStart) { //起点滑动时,重置起点的位置和进度值 pointStart = event.getX(); numStart = getProgressNum(pointStart); } else { //始点滑动时,重置始点的位置和进度值 pointEnd = event.getX(); numEnd = getProgressNum(pointEnd); } flushState();//刷新状态 } break; case MotionEvent.ACTION_UP: flushState(); break; } return true; } /** * 刷新状态和屏蔽非法值 */ private void flushState() { //起点非法值 if (pointStart < marginhorizontal) { pointStart = marginhorizontal; } //终点非法值 if (pointEnd > width - marginhorizontal) { pointEnd = width - marginhorizontal; } //防止起点位置大于终点位置(规定:如果起点位置大于终点位置,则将起点位置放在终点位置前面,即:终点可以推着起点走,而起点不能推着终点走) if (pointStart + circleRadius > pointEnd - circleRadius) { pointStart = pointEnd - 2 * circleRadius; } //防止终点把起点推到线性范围之外 if (pointEnd < marginhorizontal + 2 * circleRadius) { pointEnd = marginhorizontal + 2 * circleRadius; pointStart = marginhorizontal; } invalidate();//这个方法会导致onDraw方法重新绘制 } //进度范围 float beginNum = 0; float endNum = 1000; //计算进度数值 private float getProgressNum(float progress) { return (int) progress / (width - 2 * marginhorizontal) * (endNum - beginNum); } //初始化画笔 private void init() { paintBackground = new Paint(); paintBackground.setColor(getResources().getColor(R.color.colorBackline)); paintBackground.setStrokeWidth(backlineWidth); paintBackground.setAntiAlias(true); paintCircle = new Paint(); paintCircle.setColor(getResources().getColor(R.color.colorTipCircle)); paintCircle.setStrokeWidth(backlineWidth); paintCircle.setStyle(Paint.Style.STROKE); paintCircle.setAntiAlias(true); paintWhileCircle = new Paint(); paintWhileCircle.setColor(getResources().getColor(R.color.white)); paintCircle.setStyle(Paint.Style.FILL); paintWhileCircle.setAntiAlias(true); paintText = new Paint(); paintText.setColor(getResources().getColor(R.color.colorTipText)); paintText.setTextSize(textSize); paintText.setAntiAlias(true); paintConnectLine = new Paint(); paintConnectLine.setColor(getResources().getColor(R.color.colorTipCircle)); paintConnectLine.setStrokeWidth(backlineWidth + 5); paintConnectLine.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); //背景线 canvas.drawLine(marginhorizontal, centerVertical, width - marginhorizontal, centerVertical, paintBackground); //起点位置的外圈圆 canvas.drawCircle(pointStart, centerVertical, circleRadius, paintCircle); //起点位置的内圈圆 canvas.drawCircle(pointStart, centerVertical, circleRadius - backlineWidth, paintWhileCircle); //终点位置的外圈圆 canvas.drawCircle(pointEnd, centerVertical, circleRadius, paintCircle); //终点位置的内圈圆 canvas.drawCircle(pointEnd, centerVertical, circleRadius - backlineWidth, paintWhileCircle); //起始点连接线 canvas.drawLine(pointStart + circleRadius, centerVertical, pointEnd - circleRadius, centerVertical, paintConnectLine); //起点数值 canvas.drawText(numStart + strUnit, pointStart, marginTop, paintText); //终点数值 canvas.drawText(numEnd + strUnit, pointEnd, marginTop, paintText); } }布局文件:
<com.elink.tianyu.cardslistview.view.RangeSelectionView android:layout_width="match_parent" android:background="@android:color/white" android:layout_height="100dp" />效果图:
![](file:///D:\download\QQDownload\448238908\Image\Group\K%SWBCAA29`H9%C%QE30V@1.png)
相关文章推荐
- Android开发小知识点集锦
- Android使用MediaPlayer开发时抛IllegalStateException
- android在代码中为new出的控件设置ID及setId()异常
- In android studio,cannot load 2 facets-unknown facet type:android and android-gradle
- android检测apk及dex方法数
- Android相机实时自动对焦的完美实现
- 10. Android框架和工具之 AppMsg(消息提示)
- 设计模式之观察者模式(Observer pattern)
- android drawable中的state属性说明
- Android 数据库升级完整解决方案
- android代码中设置布局规则 LayoutParams.addRule(...)
- 设计模式之state模式
- Xamarin.Android之Splash的几种简单实现
- Android适配学习总结
- Android Studio 将Library 上传到 Jcenter
- Android获取当前时间与星期几
- 基于android的朋友圈
- Android Studio 调试过程中快捷查看断点处变量值(Ctrl+Shift+I无效)?
- Android studio Unsupported major.minor version 52.0
- Android圆形图片--自定义控件