我是靠谱客的博主 深情八宝粥,最近开发中收集的这篇文章主要介绍Android 自定义View之矩形渐变表格,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  不知道大家有没有用过一个叫唐小僧的理财产品,之前大学同学有这样一个需求,效果如下:


最近在写有关自定义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>


然后在Activity中调用


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之矩形渐变表格所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部