Android自定义View之滑动取值条
来源:互联网 发布:图片不停绕中心旋转js 编辑:程序博客网 时间:2024/06/12 00:06
Android自定义View之滑动取值条
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); }}
相关实现参数可根据需求在代码中修改!
效果图:
源码下载
3 0
- Android自定义View之滑动取值条
- android自定义View之滑动开关SlideButton
- android自定义View之滑动删除
- Android开发自定义View之滑动按钮与自定义属性
- Android开发自定义View之滑动按钮与自定义属性
- Android之滑动view
- 自定义View之滑动操作
- 自定义View之滑动解锁
- Android 自定义滑动容器View
- Android:View滑动与自定义
- Android 自定义View之随手指滑动的ToggleButton
- Android自定义View之仿知乎滑动删除Activity
- Android之自定义View实现随手势滑动的控件
- Android自定义View之刻度尺滑动功能(一)
- Android之自定义view星星评价(可滑动)
- android自定义View之自定义可置顶ScrollView,View滑动原理简析
- android自定义滑动开关控件,自定义view
- 自定义View之列表滑动删除DEMO
- Kafka使用入门
- SpringMVC几种处理器映射介绍
- Linux下的SVN服务器搭建
- 关于Git--分布式版本控制系统(1)
- HAUTOJ 1266 最大子段和
- Android自定义View之滑动取值条
- Oracle 12c 新特性之 PDB 级别闪回数据库
- app挂起token失效解决方案
- JavaScript 中创建三种消息框:警告框、确认框、提示框
- h5 表单
- 解决ajax异步传输数据,return返回为undefined的问题
- apt-get命令
- Educational Codeforces Round 16-C. Magic Odd Square
- l20范数最小化求解系数方程_贪婪组稀疏方法(Greedy group sparsity)