Android仿mac音量拖动view实现
来源:互联网 发布:照片冲印排版软件 编辑:程序博客网 时间:2024/06/07 18:49
前言
雨后江岸天破晓,老舟新客知多少;远山见竹林芳草,晨风拂绿了芭蕉。
简介
今天给大家带来的是自定义view的相关知识,我们实现的是仿mac音量加减的拖动view。我们先来看下效果图。
效果图
实现
下面我们讲一下具体的实现逻辑。
- 自定义styleable
<declare-styleable name="VolumeView"> <attr name="ball_color" format="color" /> <attr name="left_color" format="color" /> <attr name="right_color" format="color" /> <attr name="ball_radius" format="dimension" /> <attr name="start_value" format="dimension" /></declare-styleable>
ball_color:拖动小球的颜色
left_color:左边线条的颜色
right_color:右边线条的颜色
ball_radius:小球的半径
start_value:音量默认初始值
- VolumeView
/** * Created by kuangxiaoguo on 2016/11/3. */public class VolumeView extends View { private static final float DEFAULT_WIDTH = 220; private static final float DEFAULT_HEIGHT = 50; private static final int DEFAULT_BALL_RADIUS = 10; private static final int START_VALUE = 0; private Paint mBallPaint; private Paint mLeftPaint; private Paint mRightPaint; private int mBallColor; private float mBallRadius; private int mStartValue; private TouchEnum state; private float downX; private int mWidth; private int endValue; private RectF mRectF; private int mLeftColor; private int mRightColor; public VolumeView(Context context) { this(context, null); } public VolumeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public VolumeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(context, attrs, defStyleAttr); } private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VolumeView, defStyleAttr, 0); mBallColor = typedArray.getColor(R.styleable.VolumeView_ball_color, Color.GREEN); mLeftColor = typedArray.getColor(R.styleable.VolumeView_left_color, Color.BLUE); mRightColor = typedArray.getColor(R.styleable.VolumeView_right_color, Color.LTGRAY); mBallRadius = typedArray.getDimension(R.styleable.VolumeView_ball_radius, dp2px(DEFAULT_BALL_RADIUS)); mStartValue = (int) typedArray.getDimension(R.styleable.VolumeView_start_value, dp2px(START_VALUE)); typedArray.recycle(); initPaint(); } private void initPaint() { mBallPaint = new Paint(); mLeftPaint = new Paint(); mRightPaint = new Paint(); initPaint(mBallPaint, mBallColor); initPaint(mLeftPaint, mLeftColor); initPaint(mRightPaint, mRightColor); mLeftPaint.setStrokeWidth(mBallRadius / 2); mRightPaint.setStrokeWidth(mBallRadius / 2); } private void initPaint(Paint paint, int color) { paint.setAntiAlias(true); paint.setColor(color); paint.setStyle(Paint.Style.FILL); paint.setStrokeCap(Paint.Cap.BUTT); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); /** * 点击小球 */ if (downX > mStartValue && downX < mStartValue + 2 * mBallRadius) { state = TouchEnum.TOUCH_BALL; } else { /** * 点击位置位于最左边小于球的直径处 */ if (downX < 2 * mBallRadius) { downX = 0; } else if (downX > endValue) { /** * 点击位置位于最右边 */ downX = endValue; } /** * 使得mStartValue为我们按下的值刷新view * 并把state的状态置为TouchEnum.TOUCH_BALL */ mStartValue = (int) downX; invalidate(); state = TouchEnum.TOUCH_BALL; } break; case MotionEvent.ACTION_MOVE: if (state == TouchEnum.TOUCH_BALL) { float moveX = event.getX(); float moveDistance = moveX - downX; mStartValue += moveDistance; if (mStartValue < 0) { mStartValue = 0; } else if (mStartValue > endValue) { mStartValue = endValue; } invalidate(); /** * 每刷新一次view之后把moveX的值赋给downX,这样在下次又重新获取moveX,两者相减就是我们滑动的距离。 */ downX = moveX; } break; } return true; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getWidth(); endValue = (int) (mWidth - 2 * mBallRadius); mRectF = new RectF(0, 0, mWidth, h); } @Override protected void onDraw(Canvas canvas) { mBallPaint.setColor(getResources().getColor(R.color.colorGray)); canvas.drawRoundRect(mRectF, getHeight() / 5, getHeight() / 5, mBallPaint); mBallPaint.setColor(mBallColor); int verticalCenter = getHeight() / 2; canvas.drawLine(0, verticalCenter, mStartValue, verticalCenter, mLeftPaint); canvas.drawCircle(mStartValue + mBallRadius, verticalCenter, mBallRadius, mBallPaint); canvas.drawLine(mStartValue + 2 * mBallRadius, verticalCenter, mWidth, verticalCenter, mRightPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.AT_MOST) { widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_WIDTH, getResources().getDisplayMetrics()); } if (heightMode == MeasureSpec.AT_MOST) { heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEIGHT, getResources().getDisplayMetrics()); } setMeasuredDimension(widthSize, heightSize); } public enum TouchEnum { TOUCH_BALL, TOUCH_LEFT, TOUCH_RIGHT } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); }}
- xml使用VolumeView
<com.asiatravel.macvolumeview.wediget.VolumeView android:layout_width="wrap_content" android:layout_height="wrap_content" app:left_color="#4A9AF9" app:right_color="#BBB9BB" app:ball_color="#fff" app:start_value="20dp" />
总结
由于整体的实现思路比较简单,所以我们直接贴出了view源码并在一些逻辑处理的地方加了部分注释,当然,如果有哪里不明白的地方,大家可以在下面留言。
另外有需要项目源码的童鞋可以去https://github.com/kuangxiaoguo0123/MacVolumeView下载。
0 0
- Android仿mac音量拖动view实现
- Android 音量调节View
- Android 音量调节View
- Android实现View的任意拖动
- View拖动实现
- Android View 拖动
- Android View的拖动
- Android View 拖动效果
- 仿lanuch,实现左右拖动
- Android view的随手指拖动 仿IOS的悬浮圆圈效果
- SeekBar实现音量调节 仿天天动听
- 仿MIUI音量变化环形进度条实现
- Android 自定义View 实现QQ红点拖动删除效果
- Android 简单实现可全屏拖动,可点击的View
- android 实现音量调节
- Android中实现在手机屏幕上拖动View(如拖动图片)(
- Android中实现在手机屏幕上拖动View(如拖动图片)
- iOS 实现拖动一个view
- Mybatis collections应用 获取包含多个List
- CentOS 7 上编译安装MySQL 5.6.23
- Mybatis:org.postgresql.util.PSQLException: ERROR: relation "summarytdglinfo" does not ex
- 将 Session 数据存入数据库
- android 的apk反编译
- Android仿mac音量拖动view实现
- HDU 5943 Kingdom of Obsession (二分图)
- servlet基础知识
- 8. String to Integer (atoi)
- Retrofit源码解析---初始化
- 关于Studio导入项目一直卡在Building xx Gradle project info的解决办法
- hadoop中map和reduce的数量设置问题
- CSS学习 二:选择器
- EL表达式讲解