概述
不知道大家有没有用过一个叫唐小僧的理财产品,之前大学同学有这样一个需求,效果如下:
最近在写有关自定义View的demo,正好把这个也整理下,首先分析下思路
1.绘制表格,这里就是绘制横线、竖线
2.绘制左边y轴的刻度
3.根据进度绘制矩形的高度
4.设置矩形的起点和终点的渐变色
这里有个会涉及的问题和大家说一下,就是绘制时可能会出现浮点型数值运算的精度问题,如果想要更精准的计算,需要用到BigDecimal类,当然你也可以Google一下。
好了,下面进入正题:
1.第一步还是在我们的res/values/attrs.xml文件中申明我们的自定义属性:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RectGraph"> <attr name="leftFristLineColor" format="color"/> <!-- 左边第一条线的颜色 --> <attr name="rightTopColor" format="color"/> <!-- 右边第部分线条颜色 --> <attr name="leftRectStartColor" format="color"/> <!-- 左边矩形渐变开始的颜色 --> <attr name="leftRectEndColor" format="color"/> <!-- 左边矩形渐变结束的颜色 --> <attr name="rightRectStartColor" format="color"/> <!-- 右边矩形渐变开始的颜色 --> <attr name="rightRectEndColor" format="color"/> <!-- 右边边矩形渐变结束的颜色 --> <attr name="bottomLineColor" format="color"/> <!-- 底部最后一条线的颜色 --> <attr name="textLeftColor" format="color"/> <!-- 左边坐标说明的字体颜色 --> <attr name="textColor" format="color"/> <!-- 收益百分比的字体颜色 --> <attr name="textSize" format="dimension"/> <!-- 产品字体大小 --> <attr name="textPercntSize" format="dimension"/> <!-- 百分比字体大小 --> <attr name="textRectSize" format="dimension"/> <!-- 柱状图百分比字体大小 --> <attr name="rectSpeed" format="integer"/> <!-- 图形上升的速度 --> <attr name="viewHeight" format="dimension"/> <!-- View的高度 --> </declare-styleable> </resources>2.获取们我的自定义属性
/** * 左边第一条线的颜色 */ private int mLeftFristLineColor; /** * 右上方线条颜色 */ private int mRightTopColor; /** * 左边矩形渐变开始的颜色 */ private int mLeftRectStartColor; /** * 左边矩形渐变结束的颜色 */ private int mLeftRectEndColor; /** * 右边矩形渐变开始的颜色 */ private int mRightRectStartColor; /** * 右边矩形渐变结束的颜色 */ private int mRightRectEndColor; /** * 底部最后一条线的颜色 */ private int mBottomLineColor; /** * 左边坐标说明的字体颜色 */ private int mTextLeftColor; /** * 收益百分比的字体颜色 */ private int mTextColor; /** * 字体大小 */ private int mTextSize; private int mPercentTextSize; private int mRectSize; /** * View的高度 */ private int mViewHeight; private Paint mPaint; private Paint mPaintText; /** * View的边距 */ private int marginLeft; private int marginTop; private int marginRight; private int marginBottom; /** * 柱状图的高度 */ private float mLeftRectHeight; private float mRightRectHeight; /** * 控制上升的速度 */ private int mSpeed; /** * 当前绘制的高度 */ private float leftCurrent = 0; private float rightCurrent = 0; private Rect mBounds; private String rightTextContext = "本产品"; private String leftTextContext = "同期限产品"; private String yPercent[]; public RectGraph(Context context) { this(context, null); } public RectGraph(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public RectGraph(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RectGraph, defStyleAttr, 0); int count = array.getIndexCount(); for (int i = 0; i < count; i++) { int index = array.getIndex(i); switch (index) { case R.styleable.RectGraph_leftFristLineColor: mLeftFristLineColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_rightTopColor: mRightTopColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_leftRectStartColor: mLeftRectStartColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_leftRectEndColor: mLeftRectEndColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_rightRectStartColor: mRightRectStartColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_rightRectEndColor: mRightRectEndColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_bottomLineColor: mBottomLineColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_textLeftColor: mTextLeftColor = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_textColor: mTextColor = array.getColor(index, Color.WHITE); break; case R.styleable.RectGraph_rectSpeed: mSpeed = array.getColor(index, Color.BLACK); break; case R.styleable.RectGraph_textSize: mTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics())); break; case R.styleable.RectGraph_textPercntSize: mPercentTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics())); break; case R.styleable.RectGraph_textRectSize: mRectSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics())); break; case R.styleable.RectGraph_viewHeight: mViewHeight = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, 180, getResources().getDisplayMetrics())); break; } } array.recycle(); init(); }init()方法做如下操作
private void init() { /** * 绘制图像的Paint */ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); /** * 绘制文本的paint */ mPaintText = new Paint(Paint.ANTI_ALIAS_FLAG); new Thread(new Runnable() { @Override public void run() { while (rightCurrent < (getViewHeight() - marginBottom - pxToDp(1.0f)) * 0.80) { rightCurrent = rightCurrent + 1.0f; if (leftCurrent < (getViewHeight() - marginBottom - pxToDp(1.0f)) * 0.60) { leftCurrent = leftCurrent + 1.0f; mLeftRectHeight = (getViewHeight() - marginBottom - pxToDp(1.0f)) - leftCurrent; } mRightRectHeight = (getViewHeight() - marginBottom - pxToDp(1.0f)) - rightCurrent; try { Thread.sleep(mSpeed); postInvalidate(); if (Math.round(rightCurrent) == Math.round((getViewHeight() - marginBottom - pxToDp(1.0f)) * 0.80)) { Thread.sleep(100); postInvalidate(); break; } } catch (Exception e) { e.printStackTrace(); } } } }).start(); }
3.重写onDraw(),这里不需要重写onMeasuer()方法
@Override protected void onDraw(final Canvas canvas) { super.onDraw(canvas); setViewMargin(); /** * 左边第一条竖线 */ mPaint.reset(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(pxToDp(0.5f)); mPaint.setColor(mLeftFristLineColor); mPaint.setAntiAlias(true); canvas.drawLine(marginLeft, marginTop, marginLeft, getViewHeight() - marginBottom - pxToDp(1.0f), mPaint); /** * 5条横线 */ mPaint.reset(); mPaint.setColor(mRightTopColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(pxToDp(0.5f)); mPaint.setTextSize(pxToSp(getContext(), 5)); mPaint.setAntiAlias(true); /**********************************Line Start**********************************/ mPaintText.setColor(mTextLeftColor); mPaintText.setTextSize(mPercentTextSize); for (int i = 0; i < 6; i++) { if (i == 0) { /** * 第一条横线 */ canvas.drawLine(marginLeft, marginTop, getWidth(), marginTop, mPaint); /** * y轴第一个坐标刻度 */ canvas.drawText(yPercent[i], 0, marginTop + 4, mPaintText); } if (i != 0 && i != 5) { /** * 中间的横线 (getViewHeight() - marginTop) / 5 * i 将Y轴等分成5份 */ canvas.drawLine(marginLeft, (getViewHeight() - marginTop) / 5 * i, getWidth() - marginRight, (getViewHeight() - marginTop) / 5 * i, mPaint); canvas.drawText(yPercent[i], 0, (getViewHeight() - marginTop) / 5 * i, mPaintText); } if (i == 5) { /** * 最底部的横线 */ mPaint.setColor(mBottomLineColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(pxToDp(0.8f)); canvas.drawLine(marginLeft, (getViewHeight() - marginTop) / 5 * i, getWidth() - marginRight, (getViewHeight() - marginTop) / 5 * i, mPaint); canvas.drawText(yPercent[i], 0, (getViewHeight() - marginTop) / 5 * i + 5, mPaintText); } } /** * 右边最后一条线 */ mPaint.setStrokeWidth(pxToDp(0.5f)); mPaint.setColor(mRightTopColor); canvas.drawLine(getWidth() - marginRight, marginTop, getWidth() - marginRight, getViewHeight() - marginBottom, mPaint); /**********************************Line End**********************************/ /** * 左边的柱状图 */ mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); LinearGradient shader = new LinearGradient( (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2), getViewHeight() - marginBottom - pxToDp(1.5f), (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2), mLeftRectHeight, mLeftRectStartColor, mLeftRectEndColor, Shader.TileMode.MIRROR); mPaint.setShader(shader); /** * (getWidth() - marginLeft - marginRight) / 6) 将X轴等分成6份 减去1.5f是因为要在X轴上方显示柱状图 */ RectF rectF = new RectF((marginLeft + ((getWidth() - marginLeft - marginRight) / 6)), mLeftRectHeight, (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 3), getViewHeight() - marginBottom - pxToDp(1.5f)); canvas.drawRect(rectF, mPaint); /** * 右边的柱状图 */ mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); LinearGradient shader2 = new LinearGradient( (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2), getViewHeight() - marginBottom - pxToDp(1.5f), (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2), mRightRectHeight, mRightRectStartColor, mRightRectEndColor, Shader.TileMode.MIRROR); mPaint.setShader(shader2); RectF rectFRight = new RectF((marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 3), mRightRectHeight, (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 5), getViewHeight() - marginBottom - pxToDp(1.5f)); canvas.drawRect(rectFRight, mPaint); if (Math.round(rightCurrent) == Math.round((getViewHeight() - marginBottom - pxToDp(1.0f)) * 0.8)) { /** * 绘制左边柱状图的文本 */ mPaintText.setTextSize(mTextSize); mPaintText.setColor(mLeftRectEndColor); mPaintText.setStyle(Paint.Style.FILL); mPaintText.setAntiAlias(true); mBounds = new Rect(); mPaintText.getTextBounds(leftTextContext, 0, leftTextContext.length(), mBounds); float widthLeft = mBounds.width() / 2; float x = (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2 - widthLeft); float y = ((getViewHeight() - marginBottom - pxToDp(5.0f) - leftCurrent)); canvas.drawText(leftTextContext, x, y, mPaintText); String mLeftText = "7.87%"; mPaintText.getTextBounds(mLeftText, 0, mLeftText.length(), mBounds); float widthLeftP = mBounds.width() / 1.5f; float heightLeftP = mBounds.height() / 2; float x1 = (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 2 - widthLeftP); float y1 = ((getViewHeight() - marginBottom - pxToDp(1.0f) - leftCurrent / 2 + heightLeftP)); mPaintText.setColor(mTextColor); mPaintText.setTextSize(mRectSize); canvas.drawText(mLeftText, x1, y1, mPaintText); /** * 绘制右边柱状图的文本 */ float pointx1 = (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 4 - widthLeft * 0.6f); float pointy1 = ((getViewHeight() - marginBottom - pxToDp(5.0f) - rightCurrent)); mPaintText.setColor(mRightRectEndColor); mPaintText.setTextSize(mTextSize); canvas.drawText(rightTextContext, pointx1, pointy1, mPaintText); float pointx2 = (marginLeft + ((getWidth() - marginLeft - marginRight) / 6) * 4 - widthLeftP); float pointy2 = ((getViewHeight() - marginBottom - pxToDp(1.0f) - rightCurrent / 2 + heightLeftP)); mPaintText.setColor(mTextColor); mPaintText.setTextSize(mRectSize); String mRightText = "7.99%"; canvas.drawText(mRightText, pointx2, pointy2, mPaintText); } } /** * 设置边距 */ private void setViewMargin() { marginLeft = pxToDp(20); marginTop = pxToDp(4); marginRight = pxToDp(1); marginBottom = pxToDp(4); }
4.在xml文件中申明我们的控件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorBackGround" tools:context="com.customeview3.MainActivity"> <com.customeview3.RectGraph android:id="@+id/rectGraph" android:layout_width="match_parent" android:layout_height="180dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_marginTop="20dp" android:background="@color/colorBackGround" app:bottomLineColor="@color/colorBottomLine" app:leftFristLineColor="@color/colorRightEnd" app:leftRectEndColor="@color/colorLeftEnd" app:leftRectStartColor="@color/colorLeftStart" app:rectSpeed="3" app:rightRectEndColor="@color/colorRightEnd" app:rightRectStartColor="@color/colorRightStart" app:rightTopColor="@color/colorRightTop" app:textColor="@android:color/white" app:textLeftColor="@color/colorText" app:textPercntSize="6sp" app:textRectSize="15sp" app:textSize="9sp" app:viewHeight="180dp" /> </RelativeLayout>
package com.customeview3; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { private RectGraph mRectFraph; private String yPercent[] = {"8.11%", "7.99%", "7.87%", "7.75%", "7.63%", "7.51%"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRectFraph = (RectGraph) findViewById(R.id.rectGraph); mRectFraph.setViewData(yPercent); } }
源码下载地址
最后
以上就是深情八宝粥为你收集整理的Android 自定义View之矩形渐变表格的全部内容,希望文章能够帮你解决Android 自定义View之矩形渐变表格所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复