android进度条双向,安卓双向范围取值选择器,双向选择进度条,单向选择进度条自定义视图View实现...

1背景

需求要做一个时间选择器,所以自已写了一个,同时又需要做一个相同UI的单值取值拖动进度条,这个用系统的组件也很好实现,但是要两个控件实现相同的UI那还是集成在一个控件里方便,由感而写了这么一样控件

2实现效果

2c7d41b222206d9877ee3707051ca5f9.png

3实现思路

A自定义绘制方式

a先绘制圆角矩形背景

b再绘制进度

c最后再绘制拖动滑杆

d根据配置,采用不同配置进行配置,配置变量有绘制的类型为一个拖动滑杆或者为两个拖动滑杆

B重写onTouchEvent事件

a当ActionDown时,记录是否是触及到了拖动滑杆的区域,如果不是什么也不做,如果是则做个记录标志,当ActionMove时,修改进度条的值,重新绘制整个控件,并通知回调(外部可能需要监测这个值的改变)

c当DefaultAction时,清掉所有的记录标志

4实现代码

版本V1.0  DATE 2017-5-17  粗略地实现,有问题联系我

package com.hdyl.myapplication;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

/**

* Created by liugd on 2017/5/16.

*/

public class RangeProgressBar extends View {

Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

float firstValue = 50;

float maxValue = 100;

float secondValue = 75;

boolean isTwoProgress = true;

int progressColor = Color.RED;

int bgColor = Color.BLUE;

int controlColor = Color.BLACK;

int controlRadius;

int leftRightSpace;

int topBottomSpace;

public RangeProgressBar(Context context, AttributeSet attrs) {

super(context, attrs);

}

float len;

private void initViews() {

dip5 = dip2px(getContext(), 5);

leftRightSpace = dip5 * 3;

topBottomSpace = dip5*2;

len = getWidth() - 2 * leftRightSpace;

mPaint.setStyle(Paint.Style.FILL);

controlRadius = dip5 * 3;

}

public void exchangeProgressBar() {

isTwoProgress = !isTwoProgress;

invalidate();

}

RectF rectf = new RectF();

private float getRate(float value) {

return value / maxValue;

}

@Override

protected void onDraw(Canvas canvas) {

if (getWidth() == 0) {

return;

}

//画背景

mPaint.setColor(bgColor);//

rectf.left = leftRightSpace;

rectf.top = topBottomSpace;

rectf.right = len + leftRightSpace;

rectf.bottom = getHeight() - topBottomSpace;

canvas.drawRoundRect(rectf, dip5, dip5, mPaint);

//画进度条

//单进度条

if (isTwoProgress == false) {

fistPointX = getValueLen(firstValue);

rectf.right = fistPointX;

mPaint.setColor(progressColor);

canvas.drawRoundRect(rectf, dip5, dip5, mPaint);

mPaint.setColor(controlColor);

canvas.drawCircle(fistPointX, getHeight() / 2f, controlRadius, mPaint);

} else {//双进度条

fistPointX = getValueLen(firstValue);

secondPointX = getValueLen(secondValue);

rectf.left = fistPointX;

rectf.right = secondPointX;

mPaint.setColor(progressColor);

canvas.drawRoundRect(rectf, dip5, dip5, mPaint);

mPaint.setColor(controlColor);

canvas.drawCircle(fistPointX, getHeight() / 2, controlRadius, mPaint);

canvas.drawCircle(secondPointX, getHeight() / 2, controlRadius, mPaint);

}

}

private float getValueLen(float value) {

float rate = getRate(value);

float positionX = leftRightSpace + len * rate;

return positionX;

}

public int dip2px(Context context, float dpValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dpValue * scale + 0.5f);

}

int dip5;

float fistPointX, secondPointX;

private boolean isInArea(float lastPosition, float x) {

return x < lastPosition + controlRadius && lastPosition - controlRadius < x;

}

boolean isMovedFirst = false;

boolean isMovedSecond = false;

public void setFirstValue(float firstValue) {

this.firstValue = firstValue;

}

public void setSecondValue(float secondValue) {

this.secondValue = secondValue;

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

if (isInArea(fistPointX, event.getX())) {

isMovedFirst = true;

}

if (isInArea(secondPointX, event.getX())) {

isMovedSecond = true;

}

break;

case MotionEvent.ACTION_MOVE:

float newValue = maxValue * x2Rate(event.getX());

if (isMovedFirst) {

if (isTwoProgress) {

if (newValue + 10 < secondValue) {

if (ondataChanged != null) {

ondataChanged.onFirstDataChange(newValue);

}

setFirstValue(newValue);

invalidate();

}

} else {

if (ondataChanged != null) {

ondataChanged.onFirstDataChange(newValue);

}

setFirstValue(newValue);

invalidate();

}

} else if (isMovedSecond) {

if (newValue > firstValue + 10) {

if (ondataChanged != null) {

ondataChanged.onSecondDataChange(newValue);

}

setSecondValue(newValue);

invalidate();

}

}

break;

default:

isMovedSecond = false;

isMovedFirst = false;

break;

}

return true;

}

private float x2Rate(float x) {

float f = (x - leftRightSpace) / len;

if (f < 0) {

f = 0;

}

if (f > 1) {

f = 1;

}

return f;

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

initViews();

}

OnDataChanged ondataChanged;

public void setOndataChanged(OnDataChanged ondataChanged) {

this.ondataChanged = ondataChanged;

}

public interface OnDataChanged {

void onFirstDataChange(float var);

void onSecondDataChange(float var);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值