1 : 需求
可自定义更改滑动条的样式(本功能实现两种样式)
联动方式 : 滑块上更新的值通过回调给Edittext; 在Edittext上输入值,更新滑动条的游标的位置和值
高度复合性: 可根据需求,自初始化值,及返回值的调整,显示精度的可调整性
,超过滑动范围的可调整性
滑动取值条的取值方式: 可滑动,可点击
当值过大时,取值条上的值根据像素比例进行相应的缩放,使其显示完全
2: 实现
public CustomTakeValueArticle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CustomTakeValueArticle(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
上面的代码这里只构造了两个方法
初始化init(Context context)的实现如下:
/**
* 初始化
*
* @param context
*/
private void init(Context context) {
mTrunkBmp = BitmapFactory.decodeResource(getResources(), R.drawable.cursor_line_red);
mTrunkBmpDeep = BitmapFactory.decodeResource(getResources(), R.drawable.cursor_line_red_deep);
mCursorBmp = BitmapFactory.decodeResource(getResources(), R.drawable.red_cursor);
matrix = new Matrix();
matrixDeep = new Matrix();
mTrunkHight = mTrunkBmp.getHeight();
mCursorWidth = mCursorBmp.getWidth();
mCursorHight = mCursorBmp.getHeight();
mTrunkMarginTop = dip2px(context, TRUNKMARGINTOP);
mTextCursorSpace = dip2px(context, TEXT_CURSOR_SPACE);
mCursorTextSize = sp2px(context, TEXTSIZE);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
mLineWidth = dip2px(context, LINEWIDTH);
mPaint = new Paint();
mPaint.setColor(Color.RED);// 设置红色
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(mCursorTextSize);
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
mTextHight = (int) (fontMetrics.descent - fontMetrics.ascent + 0.5f);
}
这里对刻度杆滑动,未滑动,游标图的bitmap进行初始化,相关矩阵,画笔等初始化
重写onDraw方法
/**
* 重写onDraw方法
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mScaling = (getWidth() - getPaddingRight() - getPaddingLeft() - mCursorWidth)
/ (getXAxisEnd() - getXAxisStart());
if (ISCENTERVERTICALTRUNK) {
mTrunkMarginTop = (getHeight() - mTrunkHight) / 2.0f;
}
if (dstbmp != null)
dstbmp.recycle();
dstbmp = null;
drawTrunk(canvas, mTrunkMarginTop);
drawCursor(canvas);
}
这里在重写onDraw方法时取实际坐标转换为像素坐标的比例 mScaling
,刻度杆的上边界像素坐标mTrunkMarginTop,再进行重写drawTrunk(刻度杆),drawCursor(游标)的方法.
drawTrunk(刻度杆)的方法如下:
/**
* 绘制刻度条主干
*
* @param canvas
*/
private void drawTrunk(Canvas canvas, float mTrunkMarginTop) {
int leftbmp = getPaddingLeft();
int topBoundary = (int) (mTrunkMarginTop + 0.5f);
int widthbmp = getWidth() - getPaddingLeft() - getPaddingRight();
float scaw = widthbmp * 1.0f / (mTrunkBmp.getWidth());
matrix.setScale(scaw, 1.0f);
/**
* 绘制未选中的值刻度线
*/
if (dstbmp == null)
dstbmp = Bitmap.createBitmap(mTrunkBmp, 0, 0, mTrunkBmp.getWidth(), mTrunkBmp.getHeight(), matrix, true);
canvas.drawBitmap(dstbmp, leftbmp, topBoundary, null);
/**
* 绘制选中的值刻度线
*/
if (x - mXAxisStart >= 0 && mXAxisEnd - x >= 0) {
scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());
} else if (mXAxisEnd - x < 0) {
scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());
} else {
scaw = mCursorWidth / 2.0f / mTrunkBmpDeep.getWidth();
}
float scaH = mTrunkBmp.getHeight() * 1.0f / mTrunkBmpDeep.getHeight();
matrixDeep.setScale(scaw, scaH);
Bitmap dstbmpdeep = Bitmap.createBitmap(mTrunkBmpDeep, 0, 0, mTrunkBmpDeep.getWidth(),
mTrunkBmpDeep.getHeight(), matrixDeep, true);
canvas.drawBitmap(dstbmpdeep, leftbmp, topBoundary, null);
/**
* 绘制起始值和结束值(isInteger保留整数,否则精度)
*/
double tempX = getXForXvalue(mXAxisEnd);
mPaint.setColor(getTrunkTextColor());
String mEnd;
if (isInteger) {//保持整形
mEnd = String.valueOf((int) mXAxisEnd);
} else {
BigDecimal bd = new BigDecimal(mXAxisEnd);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_DOWN);
mEnd = String.valueOf(bd.doubleValue());
}
refitText(mEnd, computeMaxStringWidth(mEnd));
canvas.drawText(mEnd, (float) tempX,
mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,
mPaint);
String mStart;
if (isInteger) {//保持整形
mStart = String.valueOf((int) mXAxisStart);
} else {
BigDecimal bd = new BigDecimal(mXAxisStart);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);
mStart = String.valueOf(bd.doubleValue());
}
double tempSX = getXForXvalue(mXAxisStart);
mPaint.setColor(getTrunkTextColor());
refitText(mStart, computeMaxStringWidth(mStart));
canvas.drawText(mStart, (float) tempSX,
mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,
mPaint);
/**
* 绘制标记(起始位置和结束位置)
*/
float lineW = (mLineWidth + 0.5f);
float tempLSX = (float) getXForXvalue(mXAxisStart);
mPaint.setColor(getTrunkTextColor());
canvas.drawRect(tempLSX, mTrunkMarginTop, tempLSX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);
float tempLEX = (float) getXForXvalue(mXAxisEnd);
mPaint.setColor(getTrunkTextColor());
canvas.drawRect(tempLEX, mTrunkMarginTop, tempLEX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);
}
绘制刻度杆主干只要绘制未选中的值刻度线,选中的值刻度线,以及绘制起始值和结束值,根据isInteger来设置是否保持整形还是精度,精度值根据precision参数来设置
绘制游标drawCursor方法如下:
/**
* 绘制游标
*
* @param canvas
*/
private void drawCursor(Canvas canvas) {
/**
* 绘制游标图片
*/
canvas.drawBitmap(mCursorBmp, (int) (getXLocation() - mCursorWidth / 2.0f + 0.5f),
(int) (mTrunkMarginTop + mTrunkHight / 2.0f - mCursorHight / 2.0f + 0.5f), null);
/**
* 绘制游标文字
*/
if (isInteger) {//点差策略
scrollValue = String.valueOf(((int) value));
} else {
BigDecimal bd = new BigDecimal(scrollValue);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);
scrollValue = String.valueOf(bd.doubleValue());
}
mPaint.setColor(getCursorTextColor());
refitText(scrollValue, computeMaxStringWidth(scrollValue));
canvas.drawText(scrollValue, (int) (getXLocation() + 0.5f),
(int) (mTrunkMarginTop - mCursorHight / 2.0f + mTrunkHight / 2.0f + 0.5f - mTextCursorSpace),
mPaint);
}
该方法里主要是绘制游标图片和绘制游标文字
完整的View代码如下:
package com.example.administrator.myapplication;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Layout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.TextView;
import java.math.BigDecimal;
/**
* Created by Linhailin on 2017/2/13.
*/
public class CustomTakeValueArticle extends View {
/**
* 红色(游标和范围)颜色值
*/
private final int COLOR_PROFIT_LINE = getResources().getColor(R.color.scroll_bar_line_red);
private final int COLOR_PROFIT_TEXT = getResources().getColor(R.color.scroll_bar_text_red_label);
/**
* 绿色(游标和范围)颜色值
*/
private final int COLOR_LOSS_LINE = getResources().getColor(R.color.scroll_bar_line_bule);
private final int COLOR_LOSS_TEXT = getResources().getColor(R.color.scroll_bar_text_bule_label);
/**
* 滑动游标图片
*/
private Bitmap mCursorBmp;
/**
* 主干相关
*/
private Bitmap mTrunkBmp;
private Matrix matrix;
private Bitmap dstbmp;
private Matrix matrixDeep;
private Bitmap mTrunkBmpDeep;
/**
* 画笔
*/
private Paint mPaint;
/**
* 文字大小(PX)
*/
private float mCursorTextSize = 0;
/**
* 刻度杆的上边界像素坐标
*/
private float mTrunkMarginTop = 20;
/**
* 横坐标开始点坐标
*/
private double mXAxisStart;
/**
* 横坐标结束点坐标
*/
private double mXAxisEnd;
/**
* 实际坐标转换为像素坐标的比例
*/
private double mScaling;
/**
* 游标的宽度
*/
private float mCursorWidth = 0;
/**
* 游标的高度
*/
private int mCursorHight = 0;
/**
* 刻度杆的高度
*/
private int mTrunkHight = 0;
/**
* 刻度杆的上边界(DP)
*/
private float TRUNKMARGINTOP = 15;
/**
* 刻度杆是否居中
*/
private boolean ISCENTERVERTICALTRUNK = true;
private double x = 0;
/**
* 游标与文字之间的间隔
*/
private int mTextCursorSpace = 0;
/**
* 游标与文字之间的间隔(DP)
*/
private final float TEXT_CURSOR_SPACE = 0.5f;
/**
* 文字大小(SP)
*/
private int TEXTSIZE = 10;
/**
* 文字的高度
*/
private float mTextHight;
/**
* 是止盈
*/
private boolean isProfit = true;
private OnScrollListener onScrollListener;
private OnClickListener onClickListener;
private boolean noSetX = true;
/**
* 刻度线的粗细
*/
private float mLineWidth = 0;
/**
* 刻度线的粗细(DP)
*/
private final int LINEWIDTH = 1;
/**
* 当前游标上的数值
*/
private double value;
/**
* 当前游标上的文字
*/
private String scrollValue = "0";
/**
* 触摸滑动计数,超过,这认为不是点击事件
*/
private int mTouchSlop = 0;
/**
* 触摸时间,超过,则认为不是点击事件
*/
private int mClickTimeout = 0;
/**
* 值的精度
*/
private int precision;
/**
* 设置类型(是否需要保持精度还是整形)
*/
private Boolean isInteger;
public CustomTakeValueArticle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CustomTakeValueArticle(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
/**
* 初始化
*
* @param context
*/
private void init(Context context) {
mTrunkBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red);
mTrunkBmpDeep = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red_deep);
mCursorBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.red_cursor);
matrix = new Matrix();
matrixDeep = new Matrix();
mTrunkHight = mTrunkBmp.getHeight();
mCursorWidth = mCursorBmp.getWidth();
mCursorHight = mCursorBmp.getHeight();
mTrunkMarginTop = dip2px(context, TRUNKMARGINTOP);
mTextCursorSpace = dip2px(context, TEXT_CURSOR_SPACE);
mCursorTextSize = sp2px(context, TEXTSIZE);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
mLineWidth = dip2px(context, LINEWIDTH);
mPaint = new Paint();
mPaint.setColor(Color.RED);// 设置红色
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(mCursorTextSize);
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
mTextHight = (int) (fontMetrics.descent - fontMetrics.ascent + 0.5f);
}
/**
* 重写onDraw方法
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mScaling = (getWidth() - getPaddingRight() - getPaddingLeft() - mCursorWidth)
/ (getXAxisEnd() - getXAxisStart());
if (ISCENTERVERTICALTRUNK) {
mTrunkMarginTop = (getHeight() - mTrunkHight) / 2.0f;
}
if (dstbmp != null)
dstbmp.recycle();
dstbmp = null;
drawTrunk(canvas, mTrunkMarginTop);
drawCursor(canvas);
}
/**
* 绘制刻度条主干
*
* @param canvas
*/
private void drawTrunk(Canvas canvas, float mTrunkMarginTop) {
int leftbmp = getPaddingLeft();
int topBoundary = (int) (mTrunkMarginTop + 0.5f);
int widthbmp = getWidth() - getPaddingLeft() - getPaddingRight();
float scaw = widthbmp * 1.0f / (mTrunkBmp.getWidth());
matrix.setScale(scaw, 1.0f);
/**
* 绘制未选中的值刻度线
*/
if (dstbmp == null)
dstbmp = Bitmap.createBitmap(mTrunkBmp, 0, 0, mTrunkBmp.getWidth(), mTrunkBmp.getHeight(), matrix, true);
canvas.drawBitmap(dstbmp, leftbmp, topBoundary, null);
/**
* 绘制选中的值刻度线
*/
if (x - mXAxisStart >= 0 && mXAxisEnd - x >= 0) {
scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());
} else if (mXAxisEnd - x < 0) {
scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());
} else {
scaw = mCursorWidth / 2.0f / mTrunkBmpDeep.getWidth();
}
float scaH = mTrunkBmp.getHeight() * 1.0f / mTrunkBmpDeep.getHeight();
matrixDeep.setScale(scaw, scaH);
Bitmap dstbmpdeep = Bitmap.createBitmap(mTrunkBmpDeep, 0, 0, mTrunkBmpDeep.getWidth(),
mTrunkBmpDeep.getHeight(), matrixDeep, true);
canvas.drawBitmap(dstbmpdeep, leftbmp, topBoundary, null);
/**
* 绘制起始值和结束值(isInteger保留整数,否则精度)
*/
double tempX = getXForXvalue(mXAxisEnd);
mPaint.setColor(getTrunkTextColor());
String mEnd;
if (isInteger) {//保持整形
mEnd = String.valueOf((int) mXAxisEnd);
} else {
BigDecimal bd = new BigDecimal(mXAxisEnd);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_DOWN);
mEnd = String.valueOf(bd.doubleValue());
}
refitText(mEnd, computeMaxStringWidth(mEnd));
canvas.drawText(mEnd, (float) tempX,
mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,
mPaint);
String mStart;
if (isInteger) {//保持整形
mStart = String.valueOf((int) mXAxisStart);
} else {
BigDecimal bd = new BigDecimal(mXAxisStart);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);
mStart = String.valueOf(bd.doubleValue());
}
double tempSX = getXForXvalue(mXAxisStart);
mPaint.setColor(getTrunkTextColor());
refitText(mStart, computeMaxStringWidth(mStart));
canvas.drawText(mStart, (float) tempSX,
mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,
mPaint);
/**
* 绘制标记(起始位置和结束位置)
*/
float lineW = (mLineWidth + 0.5f);
float tempLSX = (float) getXForXvalue(mXAxisStart);
mPaint.setColor(getTrunkTextColor());
canvas.drawRect(tempLSX, mTrunkMarginTop, tempLSX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);
float tempLEX = (float) getXForXvalue(mXAxisEnd);
mPaint.setColor(getTrunkTextColor());
canvas.drawRect(tempLEX, mTrunkMarginTop, tempLEX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);
}
/**
* 绘制游标
*
* @param canvas
*/
private void drawCursor(Canvas canvas) {
/**
* 绘制游标图片
*/
canvas.drawBitmap(mCursorBmp, (int) (getXLocation() - mCursorWidth / 2.0f + 0.5f),
(int) (mTrunkMarginTop + mTrunkHight / 2.0f - mCursorHight / 2.0f + 0.5f), null);
/**
* 绘制游标文字
*/
if (isInteger) {//点差策略
scrollValue = String.valueOf(((int) value));
} else {
BigDecimal bd = new BigDecimal(scrollValue);
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);
scrollValue = String.valueOf(bd.doubleValue());
}
mPaint.setColor(getCursorTextColor());
refitText(scrollValue, computeMaxStringWidth(scrollValue));
canvas.drawText(scrollValue, (int) (getXLocation() + 0.5f),
(int) (mTrunkMarginTop - mCursorHight / 2.0f + mTrunkHight / 2.0f + 0.5f - mTextCursorSpace),
mPaint);
}
/**
* 设置游标图片
*/
public void setCursorBmp(Bitmap mCursorBitmap) {
this.mCursorBmp = mCursorBitmap;
}
/**
* 设置刻度未选中图片
*/
public void setTrunkBmp(Bitmap mTrunkBitmap) {
this.mTrunkBmp = mTrunkBitmap;
}
/**
* 设置刻度选中图片
*/
public void setTrunkBmpDeep(Bitmap mTrunkBitmapDeep) {
this.mTrunkBmpDeep = mTrunkBitmapDeep;
}
/**
* isProfit=true(是止盈)
*/
public void setIsProfit(boolean isProfit) {
this.isProfit = isProfit;
}
/**
* 根据止盈止损类型设置游标上的颜色值
*/
public int getCursorTextColor() {
return isProfit ? COLOR_PROFIT_TEXT : COLOR_LOSS_TEXT;
}
/**
* 根据止盈止损类型设置刻度干上的颜色值
*/
public int getTrunkTextColor() {
return isProfit ? COLOR_PROFIT_LINE : COLOR_LOSS_LINE;
}
/**
* X轴坐标终点
*
* @return
*/
public double getXAxisEnd() {
return mXAxisEnd;
}
/**
* X轴坐标起点
*
* @return
*/
public double getXAxisStart() {
return mXAxisStart;
}
/**
* 设置范围(最大值和最小值)
*
* @param mXAxisStart
* @param mXAxisEnd
*/
public void setValueScale(double mXAxisStart, double mXAxisEnd) {
this.mXAxisStart = mXAxisStart;
this.mXAxisEnd = mXAxisEnd;
}
/**
* 设置游标位置(在屏幕位置).在初始化时调用
*
* @param x
*/
public void setXValue(double x) {
if (mXAxisStart != 0 || mXAxisEnd != 1)
noSetX = false;
this.x = x;
this.scrollValue = String.valueOf(x);
this.value = x;
}
public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
/**
* 根据x在屏幕的像素点坐标计算实际x值
*
* @return
*/
private double getXValueForPx(double xpx) {
double d = (xpx - getPaddingLeft() - mCursorWidth / 2.0f) / mScaling + mXAxisStart;
return d;
}
private double getXForXvalue(double xvalue) {
int x = getPaddingLeft() + (int) ((xvalue - mXAxisStart) * mScaling + mCursorWidth / 2.0f + 0.5f);
return x;
}
/**
* 根据手机的分辨率从 dip 的单位 转成为 px(像素)
*/
private int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue
* @return
*/
private int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
/**
* 获取像素位置
*
* @return
*/
public double getXLocation() {
Paint.Align align = Paint.Align.LEFT;
double px = getXForXvalue(x);
if (noSetX) {
px = align == Paint.Align.LEFT ? 0 : getWidth();
}
if (px <= getPaddingLeft() + mCursorWidth / 2.0f)
px = getPaddingLeft() + mCursorWidth / 2.0f;
if (px >= getWidth() - getPaddingRight() - mCursorWidth / 2.0f)
px = getWidth() - getPaddingRight() - mCursorWidth / 2.0f;
return px;
}
/**
* 设置像素位置
*
* @param x
*/
public void setXLocation(double x) {
setXValue(getXValueForPx(x));
}
public float getTextSize() {
return mCursorTextSize;
}
/**
* 滑动接口
*/
public interface OnScrollListener {
/**
* 返回游标上的字
*
* @param x
* @return
*/
String onScroll(double x);
}
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public interface OnClickListener {
String onClick(double x);
}
private double getWidthForXValue() {
double strat = getXForXvalue(x);
return strat != 0 && strat > 0 ? strat : 1;
}
float startX = 0;
float startY = 0;
boolean isClick = true;
@SuppressLint("ClickableViewAccessibility")
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
if ((Math.abs(event.getX() - x) <= mCursorWidth) && (getXValueForPx(event.getX()) <= mXAxisEnd &&
getXValueForPx(event.getX()) >= mXAxisStart)) {
setXLocation(event.getX());
}
startX = event.getRawX();
startY = event.getRawY();
isClick = true;
break;
case MotionEvent.ACTION_MOVE:
float dx = event.getRawX() - startX;
float dy = event.getRawY() - startY;
if (onScrollListener != null) {
setXLocation(event.getX());
this.scrollValue = onScrollListener.onScroll(getXValueForPx(getXLocation()));
this.value = getXValueForPx(getXLocation());
} else if (Math.abs(dx) > mTouchSlop || Math.abs(dy) > mTouchSlop) {
isClick = false;
}
break;
case MotionEvent.ACTION_UP:
double tempX = getXForXvalue(getXLocation());
if (Math.abs(getXLocation() - tempX) <= mCursorWidth && (getXValueForPx(event.getX()) <= mXAxisEnd &&
getXValueForPx(event.getX()) >= mXAxisStart)) {
setXLocation(tempX);
} else if (isClick && event.getEventTime() - event.getDownTime() < mClickTimeout) {
//作为点击事件操作
if (onClickListener != null) {
setXLocation(event.getX());
this.scrollValue = onClickListener.onClick(getXValueForPx(getXLocation()));
this.value = getXValueForPx(getXLocation());
}
}
break;
}
invalidate();
return true;
}
/**
* 当前游标所在位置
*
* @return
*/
public double getValue() {
return this.value;
}
/**
* 当前刻度干的最大值
*
* @return
*/
public double getMaxValue() {
return this.mXAxisEnd;
}
/**
* 当前刻度干的最小值
*
* @return
*/
public double getMinValue() {
return this.mXAxisStart;
}
/**
* 增加参数(根据传入的策略类型,来设置精度)(百分比2个精度,点差不需要,价格根据instrument中的精度值设置)
*/
public void setPrecision(int precision) {
this.precision = (int) (Math.log(precision) / Math.log(10));
}
/**
* 增加参数(设置类型)
*/
public void setType(Boolean isInteger) {
this.isInteger = isInteger;
}
/**
* 获取当前字符的宽度(设置位置)
*/
private int computeMaxStringWidth(String strings) {
TextView textView = new TextView(getContext());
textView.setText(strings);
TextPaint paint = textView.getPaint();
int widthText = (int) Layout.getDesiredWidth(strings, 0,
strings.length(), paint);
return widthText;
}
/**
* 根据文字的宽度重新设置字体的大小(超过三个字符就缩小)
*
* @param text
* @param textWidth
*/
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
float[] widths = new float[text.length()];
Rect rect = new Rect();
mPaint.getTextBounds(text, 0, text.length(), rect);
int textWidths = rect.width();
mCursorTextSize = this.getTextSize();
while (textWidths > 48) {
mCursorTextSize = mCursorTextSize - 1;
mPaint.setTextSize(mCursorTextSize);
textWidths = mPaint.getTextWidths(text, widths);
}
mPaint.setTextSize(mCursorTextSize);
}
invalidate();
}
}
使用示例:
package com.example.administrator.myapplication;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import java.text.NumberFormat;
public class MainActivity extends AppCompatActivity {
private EditText content;
private EditText content1;
private CustomTakeValueArticle profitLimitScrollbar;
private CustomTakeValueArticle lossLimitScrollbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
content = (EditText) findViewById(R.id.content);
content1 = (EditText) findViewById(R.id.content1);
profitLimitScrollbar = (CustomTakeValueArticle) findViewById(R.id.profit_limit_scrollbar);
lossLimitScrollbar = (CustomTakeValueArticle) findViewById(R.id.loss_limit_scrollbar);
initScrollbar();
setScrollBarValue();
}
/**
* 初始化Scrollbar相关配置参数
*/
private void initScrollbar() {
profitLimitScrollbar.setCursorBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.red_cursor));
profitLimitScrollbar.setTrunkBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red));
profitLimitScrollbar.setTrunkBmpDeep(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red_deep));
profitLimitScrollbar.setIsProfit(true);
profitLimitScrollbar.setOnScrollListener(new CustomTakeValueArticle.OnScrollListener() {
@Override
public String onScroll(double x) {
changeScrollBarValue(x, content);
return String.valueOf(x);
}
});
profitLimitScrollbar.setOnClickListener(new CustomTakeValueArticle.OnClickListener() {
@Override
public String onClick(double x) {
changeScrollBarValue(x, content);
return String.valueOf(x);
}
});
lossLimitScrollbar.setCursorBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.blue_cursor));
lossLimitScrollbar.setTrunkBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_blue));
lossLimitScrollbar.setTrunkBmpDeep(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_blue_deep));
lossLimitScrollbar.setIsProfit(false);
lossLimitScrollbar.setOnScrollListener(new CustomTakeValueArticle.OnScrollListener() {
@Override
public String onScroll(double x) {
changeScrollBarValue(x, content1);
return String.valueOf(x);
}
});
lossLimitScrollbar.setOnClickListener(new CustomTakeValueArticle.OnClickListener() {
@Override
public String onClick(double x) {
changeScrollBarValue(x, content1);
return String.valueOf(x);
}
});
}
/**
* 点击和滑动更新实时值
*
* @param x
* @param limitValue
*/
private void changeScrollBarValue(double x, TextView limitValue) {
NumberFormat capitalNumberFormat;
capitalNumberFormat = NumberFormat.getInstance();
capitalNumberFormat.setMaximumFractionDigits(2);
capitalNumberFormat.setMinimumFractionDigits(2);
capitalNumberFormat.setGroupingUsed(false);
NumberFormat mNumberFormat;
mNumberFormat = NumberFormat.getInstance();
mNumberFormat.setMaximumFractionDigits(0);
mNumberFormat.setMinimumFractionDigits(0);
mNumberFormat.setGroupingUsed(false);
if (limitValue == content) {
limitValue.setText(capitalNumberFormat.format(x));
} else {
limitValue.setText(mNumberFormat.format(x));
}
}
/**
* 设置ScrollBar相关数据参数
*/
private void setScrollBarValue() {
profitLimitScrollbar.invalidate();
lossLimitScrollbar.invalidate();
profitLimitScrollbar.setType(false);
lossLimitScrollbar.setType(true);
profitLimitScrollbar.setPrecision(2);
profitLimitScrollbar.setXValue(50.02);
content.setText("50.02");
lossLimitScrollbar.setXValue(40);
content1.setText("40");
profitLimitScrollbar.setValueScale(0,
120);
lossLimitScrollbar.setValueScale(0,
100);
}
}
相关实现参数可根据需求在代码中修改!
源码下载