diff --git a/.idea/modules.xml b/.idea/modules.xml index 548687a..ae58549 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 9466192..8dc7015 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,5 +21,5 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' - compile project(path: ':funnellib') + implementation project(path: ':funnellib') } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f8624f5..8a66acc 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,14 +1,16 @@ \ No newline at end of file diff --git a/funnellib/src/androidTest/java/jie/com/funnellib/ExampleInstrumentedTest.java b/funnellib/src/androidTest/java/jie/com/funnellib/ExampleInstrumentedTest.java deleted file mode 100644 index 60a4215..0000000 --- a/funnellib/src/androidTest/java/jie/com/funnellib/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package jie.com.funnellib; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("jie.com.funnellib.test", appContext.getPackageName()); - } -} diff --git a/funnellib/src/main/java/jie/com/funnellib/CustomLabel.java b/funnellib/src/main/java/jie/com/funnellib/CustomLabel.java new file mode 100644 index 0000000..58c726c --- /dev/null +++ b/funnellib/src/main/java/jie/com/funnellib/CustomLabel.java @@ -0,0 +1,21 @@ +package jie.com.funnellib; + +import android.graphics.Canvas; +import android.graphics.Paint; + +/** + * Created by hj on 2019/2/22. + * 说明:开放自定义描述绘制画笔 + */ +public interface CustomLabel { + /** + * 循环绘制线后面的文字 + * @param canvas 画布 + * @param mPaintLabel 画笔 + * @param labelX 文字开始X坐标 + * @param labelY 文字开始Y坐标 + * @param index 绘制下标 + * 注意:绘制顺序是从下往上绘制!!! + */ + void drawText(Canvas canvas, Paint mPaintLabel,float labelX, float labelY,int index); +} diff --git a/funnellib/src/main/java/jie/com/funnellib/DrawHelper.java b/funnellib/src/main/java/jie/com/funnellib/DrawHelper.java deleted file mode 100644 index e6f7fa2..0000000 --- a/funnellib/src/main/java/jie/com/funnellib/DrawHelper.java +++ /dev/null @@ -1,394 +0,0 @@ -package jie.com.funnellib; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.DashPathEffect; -import android.graphics.Paint; -import android.graphics.Paint.FontMetrics; -import android.graphics.Path; -import android.graphics.PathEffect; -import android.graphics.RectF; - -import java.util.Random; - -/** - * @ClassName DrawHelper - * @Description 集中了绘制中,相关的一些小函数 - * @author XiongChuanLiang
(xcl_168@aliyun.com) - * - */ - - -public class DrawHelper { - - private static DrawHelper instance = null; - - private RectF mRectF = null; - private Path mPath = null; - private Paint mPaint = null; - - public DrawHelper(){} - - public static synchronized DrawHelper getInstance() - { - if(instance == null){ - instance = new DrawHelper(); - } - return instance; - } - - private void initRectF() - { - if(null == mRectF) - mRectF = new RectF(); - } - - private void initPath() - { - if(null == mPath) - { - mPath = new Path(); - }else{ - mPath.reset(); - } - } - - private void initPaint() - { - if(null == mPaint) - { - mPaint = new Paint(); - }else{ - mPaint.reset(); - } - } - - - /** - * 得到一个随机颜色 - * @return 随机颜色 - */ - public int randomColor() { - Random random = new Random(); - int red = random.nextInt(256) ; - int green = random.nextInt(256) ; - int blue = random.nextInt(256); - return Color.rgb(red, green, blue); - } - - /** - * 通过透明度,算出对应颜色的浅色应当是什么效果 - * @param color 颜色 - * @param alpha 透明度 - * @return 浅色 - */ - public int getLightColor(int color,int alpha) - { - initPaint(); - mPaint.setColor(color); - mPaint.setAlpha(alpha); - return mPaint.getColor(); - } - - /** - * 得到深色 - * @param color 颜色 - * @return 深色 - */ - public int getDarkerColor(int color){ - float[] hsv = new float[3]; - Color.colorToHSV(color, hsv); - hsv[1] = hsv[1] + 0.1f; - hsv[2] = hsv[2] - 0.1f; - int darkerColor = Color.HSVToColor(hsv); - return darkerColor ; - } - - /** - * 得到单个字的高度 - * @param paint 画笔 - * @return 高度 - */ - public float getPaintFontHeight(Paint paint) - { - FontMetrics fm = paint.getFontMetrics(); - return (float) Math.ceil(fm.descent - fm.ascent); - } - - /** - * 得到字符串的宽度 - * @param paint 画笔 - * @param str 字符串 - * @return 宽度 - */ - public float getTextWidth(Paint paint, String str) - { - if(str.length() == 0) return 0.0f; - //float width = Math.abs(paint.measureText(str, 0, str.length())); - return paint.measureText(str, 0, str.length()); - } - - /** - * 用于计算文字的竖直累加高度 - * @param paint 画笔 - * @param str 字符串 - * @return 高度 - */ - public float calcTextHeight(Paint paint, String str) - { - if(str.length() == 0) return 0; - return getPaintFontHeight(paint) * str.length(); - } - - /** - * 绘制旋转了指定角度的文字 - * @param text 文字 - * @param x X坐标 - * @param y y坐标 - * @param paint 画笔 - * @param angle 角度 - */ - public void drawRotateText( String text , - float x ,float y,float angle, - Canvas canvas, - Paint paint - ){ - if("" == text|| text.length() == 0 ) return; - - if(angle != 0){ - canvas.rotate(angle, x, y); - //canvas.drawText(text, x, y, paint); - drawText(canvas,paint,text,x,y); - canvas.rotate(-1 * angle, x, y); - }else{ - //canvas.drawText(text, x, y, paint); - drawText(canvas,paint,text,x,y); - } - } - -// /** -// * 绘制等腰三角形 -// * @param baseLine 底线长度 -// * @param baseLnCentX 底线中心点X坐标 -// * @param baseLnCentY 底线中心点Y坐标 -// * @param direction 三角形方向 -// * @param style 填充风格 -// * @param canvas 画布 -// * @param paint 画笔 -// */ -// public void drawTrigangle( float baseLine, -// float baseLnCentX, -// float baseLnCentY, -// XEnum.TriangleDirection direction, -// XEnum.TriangleStyle style, -// Canvas canvas, -// Paint paint) -// { -// // 计算偏移量 -// int offset = (int)(baseLine / 2 * Math.tan(60 * Math.PI / 180)); -// -// initPath(); -// // 计算三角形3个顶点的坐标 -// switch (direction) -// { -// case UP: //向上 -// -// mPath.moveTo(baseLnCentX- baseLine / 2 , baseLnCentY); -// mPath.lineTo(baseLnCentX + baseLine / 2,baseLnCentY); -// mPath.lineTo(baseLnCentX,baseLnCentY - offset); -// mPath.close(); -// break; -// -// case DOWN: //向下 -// -// mPath.moveTo( baseLnCentX - baseLine / 2 , baseLnCentY); -// mPath.lineTo(baseLnCentX + baseLine / 2,baseLnCentY); -// mPath.lineTo(baseLnCentX,baseLnCentY + offset); -// mPath.close(); -// -// break; -// case LEFT: //向左 -// -// mPath.moveTo(baseLnCentX , baseLnCentY - baseLine / 2); -// mPath.lineTo(baseLnCentX , baseLnCentY + baseLine / 2); -// mPath.lineTo(baseLnCentX - offset ,baseLnCentY); -// mPath.close(); -// -// break; -// case RIGHT: //向右 -// -// mPath.moveTo(baseLnCentX , baseLnCentY - baseLine / 2); -// mPath.lineTo(baseLnCentX , baseLnCentY + baseLine / 2); -// mPath.lineTo(baseLnCentX + offset ,baseLnCentY); -// mPath.close(); -// break; -// } -// -// -// //三角形的填充风格 -// switch (style) -// { -// case OUTLINE : //空心 -// paint.setStyle(Paint.Style.STROKE); -// break; -// case FILL : //FILL -// paint.setStyle(Paint.Style.FILL); -// break; -// } -// canvas.drawPath(mPath,paint); -// mPath.reset(); -// } - - - public PathEffect getDotLineStyle() - { - return( new DashPathEffect(new float[] { 2, 2, 2, 2}, 1)); - } - - public PathEffect getDashLineStyle() - { - //虚实线 - return(new DashPathEffect(new float[] { 4, 8, 5, 10}, 1)); - } - - - /** - * 绘制点 - * @param startX 起始点X坐标 - * @param startY 起始点Y坐标 - * @param stopX 终止点X坐标 - * @param stopY 终止点Y坐标 - * @param canvas 画布 - * @param paint 画笔 - */ - public void drawDotLine(float startX,float startY, - float stopX,float stopY, - Canvas canvas, - Paint paint) - { - //PathEffect effects = new DashPathEffect(new float[] { 2, 2, 2, 2}, 1); - paint.setPathEffect(getDotLineStyle()); - canvas.drawLine(startX, startY, stopX, stopY, paint); - paint.setPathEffect(null); - } - - /** - * 绘制虚实线 - * @param startX 起始点X坐标 - * @param startY 起始点Y坐标 - * @param stopX 终止点X坐标 - * @param stopY 终止点Y坐标 - * @param canvas 画布 - * @param paint 画笔 - */ - public void drawDashLine(float startX,float startY, - float stopX,float stopY, - Canvas canvas, - Paint paint) - { - //虚实线 - //PathEffect effects = new DashPathEffect(new float[] { 4, 8, 5, 10}, 1); - paint.setPathEffect(getDashLineStyle()); - canvas.drawLine(startX, startY, stopX, stopY, paint); - paint.setPathEffect(null); - } - - -// //下次应当做的:虚实线 比例的灵活定制,线的阴影渲染 -// public void drawLine(XEnum.LineStyle style, -// float startX,float startY, -// float stopX,float stopY, -// Canvas canvas, -// Paint paint -// ) -// { -// -// switch(style) -// { -// case SOLID: -// canvas.drawLine(startX, startY, stopX, stopY, paint); -// break; -// case DOT: -// drawDotLine(startX, startY, stopX, stopY, canvas,paint); -// break; -// case DASH: -// //虚实线 -// drawDashLine(startX, startY, stopX, stopY, canvas,paint); -// break; -// } -// } - - /** - * 绘制图中显示所占比例 的扇区 - * @param paintArc 画笔 - * @param cirX x坐标 - * @param cirY y坐标 - * @param radius 半径 - * @param startAngle 偏移角度 - * @param sweepAngle 当前角度 - * @throws Exception 例外 - */ - public void drawPercent(Canvas canvas, Paint paintArc, - final float cirX, - final float cirY, - final float radius, - final float startAngle, - final float sweepAngle, boolean useCenter) throws Exception - { - try{ - initRectF(); - mRectF.left = cirX - radius; - mRectF.top = cirY - radius ; - mRectF.right = cirX + radius ; - mRectF.bottom = cirY + radius ; - //在饼图中显示所占比例 - canvas.drawArc(mRectF, startAngle, sweepAngle, useCenter, paintArc); - mRectF.setEmpty(); - }catch( Exception e){ - throw e; - } - } - - public void drawPathArc(Canvas canvas, Paint paintArc, - final float cirX, - final float cirY, - final float radius, - final float startAngle, - final float sweepAngle) throws Exception - { - try{ - initRectF(); - mRectF.left = cirX - radius; - mRectF.top = cirY - radius ; - mRectF.right = cirX + radius ; - mRectF.bottom = cirY + radius ; - //弧形 - initPath(); - mPath.addArc(mRectF,startAngle, sweepAngle); - canvas.drawPath(mPath, paintArc); - mRectF.setEmpty(); - mPath.reset(); - }catch( Exception e){ - throw e; - } - } - - //绘制有换行的文本 - public float drawText(Canvas canvas, Paint paint, String text, float x, float y) - { - if(text.length() > 0 ) - { - if( text.indexOf("\n") > 0 ){ - float height = getPaintFontHeight(paint); - String[] arr = text.split("\n"); - for(int i=0;i mDataSet; + /* + * 梯形画笔 + * */ private Paint mPaint = null; + /* + * 间隔线画笔 + * */ private Paint mPaintFunnelLine = null; - + /* + * 描述画笔 + * */ private Paint mPaintLabel = null; + /* + * 线 画笔 + * */ private Paint mPaintLabelLine = null; + private float mRight = 0.0f; private float mBottom = 0.0f; private Context mContext; private float mLineWidth; //线的长度 private float mLineTextSpace; //字与线的间距 - private float mLastLineOffset; + private float mLastLineOffset; //最底部从中心点向两边的偏移量 + private float mTotalHeight; //单个梯形的目标高度 + private int count; //漏斗的个数 + private float mPlotRight; + private float mPlotLeft; + private float mPlotBottom; + private float mPlotTop; + + /* + * 中心点坐标,绘制是从下往上,这个坐标是最底部那跟线的中心点 + * 最后一根线的长度= mLastLineOffset*2 + * */ + private float mCenterX; + + /* + * 图表总高度 + * */ + private float mPlotHeight; + /* + * 图表总宽度 + * */ + private float mPlotWidth; + + //最顶部的线的宽度 + private float mTopMaxLineWidth; + + /* + * 自定义绘制描述文字接口 + * */ + private CustomLabel mCustomLabel; + + /* + * 漏斗之间线的颜色 + * */ + private int mFunnelLineColor; + /* + * 漏斗之间线的粗细 + * */ + private float mFunnelLineStoke; + + /* + * 漏斗与描述之间线的粗细 + * */ + private float mLineStoke; - private ICustomText mCustomText; + /* + * 描述文字颜色 + * */ + private int mLabelColor; + + /* + * 描述文字大小 + * */ + private float mLabelSize; public FunnelView(Context context) { super(context); @@ -55,41 +126,40 @@ private void initView(Context context, AttributeSet attributeSet) { this.mContext = context; if (attributeSet != null) { TypedArray ta = context.obtainStyledAttributes(attributeSet, R.styleable.FunnelView); - mLineWidth = ta.getDimension(R.styleable.FunnelView_lineWidth, Util.dip2px(context, 12)); - mLineTextSpace = ta.getDimension(R.styleable.FunnelView_lineTextSpace, Util.dip2px(context, 7)); - mLastLineOffset = ta.getDimension(R.styleable.FunnelView_lastLineOffset, Util.dip2px(context, 20)); + mLineWidth = ta.getDimension(R.styleable.FunnelView_lineWidth, dip2px(context, 12)); + mLineTextSpace = ta.getDimension(R.styleable.FunnelView_lineTextSpace, dip2px(context, 7)); + mLastLineOffset = ta.getDimension(R.styleable.FunnelView_lastLineOffset, dip2px(context, 20)); + mTotalHeight = ta.getDimension(R.styleable.FunnelView_totalHeight, dip2px(context, 30)); + mFunnelLineStoke = ta.getDimension(R.styleable.FunnelView_funnelLineStoke, 5); + mFunnelLineColor = ta.getColor(R.styleable.FunnelView_funnelLineColor, Color.WHITE); + mLineStoke = ta.getDimension(R.styleable.FunnelView_lineStoke, 3f); + mLabelColor = ta.getColor(R.styleable.FunnelView_labelColor, Color.BLACK); + mLabelSize = ta.getDimension(R.styleable.FunnelView_labelSize, sp2px(mContext, 12)); ta.recycle(); } - Util.disableHardwareAccelerated(this); + disableHardwareAccelerated(this); chartRender(); } - public void setChartData(List chartData) { + public void setChartData(@NonNull List chartData) { this.mDataSet = chartData; + count = mDataSet.size(); + mTopMaxLineWidth = mLastLineOffset + getHalfWidthOffset() * count; invalidate(); } - public void setLeftPadding(float leftPadding) { - setCenterX(leftPadding); - } - private void chartRender() { mPaintLabel = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaintFunnelLine = new Paint(Paint.ANTI_ALIAS_FLAG); - mPaintFunnelLine.setStrokeWidth(5); - mPaintFunnelLine.setColor(Color.WHITE); + mPaintFunnelLine.setStrokeWidth(mFunnelLineStoke); + mPaintFunnelLine.setColor(mFunnelLineColor); mPaintLabelLine = new Paint(Paint.ANTI_ALIAS_FLAG); mPaintLabel.setTextAlign(Paint.Align.LEFT); - try { - mPaintLabel.setColor(Color.parseColor("#666666")); - mPaintLabel.setTextSize(Util.sp2px(mContext, 12)); - mPaintLabelLine.setStrokeWidth(3f); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + mPaintLabel.setColor(mLabelColor); + mPaintLabel.setTextSize(mLabelSize); + mPaintLabelLine.setStrokeWidth(mLineStoke); } @Override @@ -114,6 +184,16 @@ protected void onDraw(Canvas canvas) { } } + private void renderPlot(Canvas canvas) { + if (null == mDataSet) { + Log.e(TAG, "FunnelView=>未设置数据源!"); + return; + } + float funnelHeight = mPlotHeight / count; + float cx = mCenterX; + renderPlotDesc(canvas, cx, funnelHeight); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), @@ -134,26 +214,16 @@ private int measureWidth(int measureSpec) { } private int measureHeight(int measureSpec) { - int result = 100; + int result = (int) mTotalHeight * count; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { //fill_parent result = specSize; - } else if (specMode == MeasureSpec.AT_MOST) { //wrap_content - result = Math.min(result, specSize); } return result; } - private float mPlotRight; - private float mPlotLeft; - private float mPlotBottom; - private float mPlotTop; - private float mCenterX; - - private float mPlotHeight; - private float mPlotWidth; /** * 计算图的显示范围,依屏幕px值来计算. @@ -165,15 +235,9 @@ private void calcPlotRange() { mPlotRight = mRight - getPaddingRight(); mPlotWidth = Math.abs(mPlotRight - mPlotLeft); mPlotHeight = Math.abs(mPlotBottom - mPlotTop); - - mCenterX = Util.dip2px(mContext, 92 + 45); - } - - public void setCenterX(float centerX) { - this.mCenterX = centerX; + mCenterX = (int) mTopMaxLineWidth + mPlotLeft; } - /** * 返回图的数据源 * @@ -218,15 +282,15 @@ private void renderPlotDesc(Canvas canvas, float cx, float funnelHeight) { } //根据数量来调整倾斜角度,如果需要实现别的倾斜效果只需调整下面的算法 if (count <= 4) { - halfWidth += Util.dip2px(mContext,17); + halfWidth += dip2px(mContext, 17); } else if (count <= 6) { - halfWidth += Util.dip2px(mContext,13); + halfWidth += dip2px(mContext, 13); } else if (count <= 8) { - halfWidth += Util.dip2px(mContext,10); + halfWidth += dip2px(mContext, 10); } else if (count <= 10) { - halfWidth += Util.dip2px(mContext,7); + halfWidth += dip2px(mContext, 7); } else { - halfWidth += Util.dip2px(mContext,5); + halfWidth += dip2px(mContext, 5); } bottomY = sub(mPlotBottom, i * funnelHeight); @@ -236,6 +300,7 @@ private void renderPlotDesc(Canvas canvas, float cx, float funnelHeight) { pStart.y = bottomY - funnelHeight; pStop.x = cx + mLastLineOffset + halfWidth; + Log.i("HJ", pStop.x + "--cx:" + mLastLineOffset + "--halfWidth:" + halfWidth); pStop.y = bottomY - funnelHeight; path.lineTo(pStop.x, pStop.y); //画右边的线 path.lineTo(pStart.x, pStart.y); //画左边的线 @@ -245,11 +310,25 @@ private void renderPlotDesc(Canvas canvas, float cx, float funnelHeight) { if (i != count - 1) { //绘制中间的线 canvas.drawLine(pStart.x, pStart.y, pStop.x, pStop.y, mPaintFunnelLine); } - renderLabels(canvas, d, cx, labelY, d.getColor(), (int) (pStop.x - cx)); + renderLabels(canvas, d, cx, labelY, d.getColor(), (int) (pStop.x - cx), i); } } + private float getHalfWidthOffset() { + if (count <= 4) { + return dip2px(mContext, 17); + } else if (count <= 6) { + return dip2px(mContext, 13); + } else if (count <= 8) { + return dip2px(mContext, 10); + } else if (count <= 10) { + return dip2px(mContext, 7); + } else { + return dip2px(mContext, 5); + } + } + /* * 设置线的宽度 * */ @@ -267,67 +346,25 @@ public void setLineTextSpace(float mLineTextSpace) { /* * 自定义描述绘制 * */ - public void addCustomDrawText(ICustomText iCustomText) { - this.mCustomText = iCustomText; + public void addCustomDrawLabel(CustomLabel iCustomLabel) { + this.mCustomLabel = iCustomLabel; } //画线和字 - private void renderLabels(Canvas canvas, IFunnelData data, float cx, float y, int color, int width/*每一个四边形的宽度的一半*/) { + private void renderLabels(Canvas canvas, IFunnelData data, float cx, float y, int color, int halfWidth, int i) { if (data == null) return; mPaintLabelLine.setColor(color); - float lineX = cx + width + mLineWidth; + float lineX = cx + halfWidth + mLineWidth; canvas.drawLine(cx, y, lineX, y, mPaintLabelLine); float labelX = lineX + mLineTextSpace; - float labelY = y + (DrawHelper.getInstance().getPaintFontHeight(mPaintLabel) / 3); - if (mCustomText == null) { - setLableUi(); + float labelY = y + getPaintFontHeight(mPaintLabel) / 3; + if (mCustomLabel == null) { canvas.drawText(data.getLabel(), labelX, labelY, mPaintLabel); // float labelWidth = DrawHelper.getInstance().getTextWidth(mPaintLabel, data.getLabel()); // setNumUi(); // canvas.drawText(data.getNumUnit(), labelX + labelWidth, labelY, mPaintLabel); } else { - mCustomText.drawText(canvas, labelX, labelY); - } - } - - - /** - * 设置客户字体 - */ - private void setLableUi() { - mPaintLabel.setColor(Color.parseColor("#666666")); - mPaintLabel.setFakeBoldText(false); - } - - /** - * 设置数量字体 - */ - private void setNumUi() { - mPaintLabel.setColor(Color.parseColor("#333333")); - mPaintLabel.setFakeBoldText(true); - } - - private void renderPlot(Canvas canvas) { - if (null == mDataSet) { - Log.e(TAG, "数据源为空!"); - return; + mCustomLabel.drawText(canvas, mPaintLabel, labelX, labelY, i); } - int count = mDataSet.size(); - float funnelHeight = mPlotHeight / count; - float cx = mCenterX; - renderPlotDesc(canvas, cx, funnelHeight); - } - - /** - * 减法运算 - * - * @param v1 参数1 - * @param v2 参数2 - * @return 运算结果 - */ - private float sub(float v1, float v2) { - BigDecimal bgNum1 = new BigDecimal(Float.toString(v1)); - BigDecimal bgNum2 = new BigDecimal(Float.toString(v2)); - return bgNum1.subtract(bgNum2).floatValue(); } } diff --git a/funnellib/src/main/java/jie/com/funnellib/ICustomText.java b/funnellib/src/main/java/jie/com/funnellib/ICustomText.java deleted file mode 100644 index 6dd1d05..0000000 --- a/funnellib/src/main/java/jie/com/funnellib/ICustomText.java +++ /dev/null @@ -1,11 +0,0 @@ -package jie.com.funnellib; - -import android.graphics.Canvas; - -/** - * Created by hj on 2019/2/22. - * 说明: - */ -public interface ICustomText { - void drawText(Canvas canvas,float labelX,float labelY); -} diff --git a/funnellib/src/main/java/jie/com/funnellib/Util.java b/funnellib/src/main/java/jie/com/funnellib/Util.java index 05548fc..5e3e9bd 100644 --- a/funnellib/src/main/java/jie/com/funnellib/Util.java +++ b/funnellib/src/main/java/jie/com/funnellib/Util.java @@ -1,9 +1,12 @@ package jie.com.funnellib; import android.content.Context; +import android.graphics.Paint; import android.util.TypedValue; import android.view.View; +import java.math.BigDecimal; + /** * Created by hj on 2019/2/22. * 说明: @@ -37,4 +40,29 @@ static void disableHardwareAccelerated(View view) { } } + + /** + * 得到单个字的高度 + * @param paint 画笔 + * @return 高度 + */ + static float getPaintFontHeight(Paint paint) + { + Paint.FontMetrics fm = paint.getFontMetrics(); + return (float) Math.ceil(fm.descent - fm.ascent); + } + + /** + * 减法运算 + * + * @param v1 参数1 + * @param v2 参数2 + * @return 运算结果 + */ + static float sub(float v1, float v2) { + BigDecimal bgNum1 = new BigDecimal(Float.toString(v1)); + BigDecimal bgNum2 = new BigDecimal(Float.toString(v2)); + return bgNum1.subtract(bgNum2).floatValue(); + } + } diff --git a/funnellib/src/main/res/values/attrs.xml b/funnellib/src/main/res/values/attrs.xml index 70b2d9f..280ce58 100644 --- a/funnellib/src/main/res/values/attrs.xml +++ b/funnellib/src/main/res/values/attrs.xml @@ -4,5 +4,11 @@ + + + + + + \ No newline at end of file diff --git a/funnellib/src/test/java/jie/com/funnellib/ExampleUnitTest.java b/funnellib/src/test/java/jie/com/funnellib/ExampleUnitTest.java deleted file mode 100644 index c5d603e..0000000 --- a/funnellib/src/test/java/jie/com/funnellib/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package jie.com.funnellib; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file