图一:LineChart;图二:YearLineChart;图三:PieChart
记:不想导别人的库,只是简单的几个图,自己做的,很粗糙,但是可以根据需求自己改改。分享一下。
改进空间:添加动画、对象复用、以及绘制文字时的坐标计算
知识来源:小专栏(https://xiaozhuanlan.com/)作者GcsSloop的安卓自定义View教程,不高深但是很实 用,第一次体验在网上花钱学知识。
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.List;
/**
* Created by mystery_code on 2018/7/6 0006.
* Description:
* Update:
*/
public class LineChart extends View {
public LineChart(Context context) {
this(context, null);
}
public LineChart(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public LineChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LineChart);
horizontalLine=ta.getDimensionPixelSize(R.styleable.LineChart_backgroundLineWidth,1);
radius=ta.getDimensionPixelSize(R.styleable.LineChart_radius,10);
textSize=ta.getDimensionPixelSize(R.styleable.LineChart_tSize,13);
int textColor=ta.getColor(R.styleable.LineChart_tColor,getResources().getColor(R.color.colorAccent));
int lineColor=ta.getColor(R.styleable.LineChart_backgroundLineColor,getResources().getColor(R.color.colorPrimary));
limit=ta.getInt(R.styleable.LineChart_limitPoint,7);
lineWidth=ta.getDimensionPixelSize(R.styleable.LineChart_lineWidth,1);
if (null == paint) {
paint = new Paint();
}
if (null == linePaint) {
linePaint = new Paint();
}
paint.setColor(textColor);
// paint.setColor(Color.parseColor("#00e1b3"));
paint.setAntiAlias(true);
paint.setTextSize(textSize);
paint.setStrokeWidth(lineWidth);
linePaint.setColor(lineColor);
// linePaint.setColor(Color.parseColor("#999999"));
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(horizontalLine);
ta.recycle();
}
private List list;
//折线、圆、文字画笔
private Paint paint;
//背景线
private Paint linePaint;
//背景线粗细
private float horizontalLine ;
//圆点半径
private float radius;
//文字大小
private float textSize ;
//折线宽度
private float lineWidth;
//背景线粗细
// private float horizontalLine = DensityUtil.dip2px(1f);
// //圆点半径
// private float radius = DensityUtil.dip2px(10f);
// //文字大小
// private float textSize = DensityUtil.sp2px(13f);
// //折线宽度
// private float lineWidth = DensityUtil.dip2px(2f);
//文字间距
private int dis;
//单元距离
private int unitDis = 0;
//元素x坐标
private int inX = 0;
//折线图上部需要留的距离:文字边框+圆点半径
private float top;
//折线图下部需要留的距离:文字边框+圆点半径
private float bottom;
//可见原点个数
private int limit;
public void setData(List list) {
this.list = list;
if (null == p) {
p = new Path[list.size()];
}
if (null == regions) {
regions = new Region[list.size()];
}
invalidate();
}
private Path[] p;
private float height;
private float width;
private float preX;
private float preY;
/**
* 注意:mRegion这里使用来做圆点点击判断的集合,regions是所有点的集合
*/
private Region[] regions;
private Region mRegion;
//剩余高度值
private float retainH;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//计算最大值和最小值,从其差值来计算单位距离
int max = find(list, 1);
int min = find(list, 0);
//初始化x坐标及top和bottom值
Rect rectText = new Rect();
paint.getTextBounds("2000", 0, 4, rectText);
dis= (int) ((screenWidth-rectText.width())/(limit-1)-rectText.width());//根据原点个数限制计算点与点之间的距离
top=rectText.height()+radius*1.5f;//1.5倍是为选中变化做准备
bottom=rectText.height()+radius*1.5f;//同上
//剩余高度值需要减去顶、底部预留距离以使折线及原点绘制时不会遮蔽文字
retainH=height-top-bottom;
//
float h=height-bottom;
//画背景灰线的宽度
float stopline=screenWidth*(list.size()-1)/6;
//画背景灰线
canvas.drawLine(0, h / 5, stopline, h / 5, linePaint);
canvas.drawLine(0, 2 * h / 5, stopline, 2 * h / 5, linePaint);
canvas.drawLine(0, 3 * h / 5, stopline, 3 * h / 5, linePaint);
canvas.drawLine(0, 4 * h / 5, stopline, 4 * h / 5, linePaint);
canvas.drawLine(0, h, stopline, h, linePaint);
/**
* 以下在计算文字时的rect可复用,此处未做改变
*/
if (null != list && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
String year = list.get(i).getYear().trim();
int count = list.get(i).getCount();
//年份画布计算
Rect rect = new Rect();
paint.getTextBounds(year, 0, year.length(), rect);
if (i == 0) {
inX=rect.width()/2;
unitDis = rectText.width() + dis;
}
//数字计算
String temp = count + "";
Rect rect1 = new Rect();
paint.getTextBounds(temp, 0, temp.length(), rect1);
//画年份
canvas.drawText(year, inX-rect.width()/2, height, paint);
//画圆点
float pointY = retainH / (max - min) * (count - min);
if (null != p && null != regions) {
p[i] = new Path();
regions[i] = new Region();
if (list.get(i).isBig()) {
/**
* 说明:原点高度的计算:【剩余高度值-原点的高度(因为其方向与坐标轴相反)】+顶部留白的高度
*/
p[i].addCircle(inX, retainH - pointY+top, radius * 1.5f, Path.Direction.CW);
} else
p[i].addCircle(inX, retainH - pointY+top, radius, Path.Direction.CW);
regions[i].setPath(p[i], mRegion);
//这里使用drawPath进行原点绘制而不是drawCircle的原因:需要对原点的点击事件做处理,参考onTouchEvent
canvas.drawPath(p[i], paint);
}
//画数字
canvas.drawText(count + "", inX - rect1.width() / 2, (retainH - pointY+top) - radius - rect.height() / 2, paint);
//画连线
if (i != 0)
canvas.drawLine(preX, preY, inX, retainH - pointY+top, paint);
preX = inX;
preY = retainH - pointY+top;
inX += rectText.width() + dis;//rect.width的值是变化的并不是不变的,但是rectText.w是不变的
}
scrollX = getScrollX();
width = inX;
}
}
/**
* 获取最值
* @param list 传入列表
* @param type 1:最大值;0:最小值
* @return
*/
private int find(List list, int type) {
int num = 0;
for (int i = 0; i < list.size(); i++) {
int count = list.get(i).getCount();
if (0 == type) {
num = num < count ? num : count;
} else if (1 == type) {
num = num > count ? num : count;
}
}
return num;
}
// @Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// int width=MeasureSpec.getSize(widthMeasureSpec);
// }
private int screenWidth;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.height = h;
mRegion = new Region(0, 0, (list.size()+10)*1000, (int)height);
screenWidth=w;
}
//手指接触时的x,y坐标
private float startX;
private float startY;
//中介数
private float tempX;
//是否可以点击(单次滑动不再视为点击)
private boolean isClick;
//每次滑动的距离
private int scrollX;
//原点变大变小的记录参数
private int tempIndex;
//控制滑动边沿
private int count = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
tempX = startX = event.getX();
startY = event.getY();
isClick = true;
break;
case MotionEvent.ACTION_MOVE:
float currentX = event.getX();
//右移
if (currentX - tempX > unitDis) {
count--;
if (count < 0 || count > list.size() - limit) {
count++;
return true;
}
//右移取负值是坐标系本质存在的
scrollBy((int) -unitDis, 0);
scrollX = getScrollX();
tempX = currentX;
invalidate();
isClick = false;
} else //左移
if (currentX - tempX < -unitDis) {
count++;
if (count < 0 || count > list.size() - limit) {
count--;
return true;
}
scrollBy((int) unitDis, 0);
scrollX = getScrollX();
tempX = currentX;
invalidate();
isClick = false;
} else {
}
break;
case MotionEvent.ACTION_UP:
float endX = event.getX();
float endY = event.getY();
//手指抬起时,是否是点击事件(通过接口自定义点击事件)
if (isClick && Math.abs(endX - startX) < unitDis && Math.abs(endY - startY) < unitDis) {
if (null != clickEvent) {
if (null == regions) {
return true;
}
for (int i = 0; i < regions.length; i++) {
//判断手指(endX + scrollX, endY)是否在原点的范围regions[i]内
if (regions[i].contains((int) (endX + scrollX), (int) endY)) {
//原点大小
if (tempIndex==i){
list.get(i).setBig(!list.get(i).isBig());
}else {
list.get(tempIndex).setBig(false);
list.get(i).setBig(true);
}
tempIndex = i;
invalidate();
//事件处理
clickEvent.click(i);
}
}
}
}
break;
}
return true;
}
private ClickEvent clickEvent;
public void setClickEvent(ClickEvent clickEvent) {
this.clickEvent = clickEvent;
}
public interface ClickEvent {
void click(int position);
}
// public class YearEntity {
// private String year;
// private int count;
// private boolean big;
//
// public String getYear() {
// return year;
// }
//
// public void setYear(String year) {
// this.year = year;
// }
//
// public int getCount() {
// return count;
// }
//
// public void setCount(int count) {
// this.count = count;
// }
//
// public YearEntity(String year, int count) {
// this.year = year;
// this.count = count;
// }
//
// public boolean isBig() {
// return big;
// }
//
// public void setBig(boolean big) {
// this.big = big;
// }
//
// }
}
自定义属性:values/attrs.xml(自建)
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import com.dataadt.qitongcha.utils.DensityUtil;
import com.dataadt.qitongcha.utils.EmptyUtil;
import com.dataadt.qitongcha.utils.LogUtil;
import java.util.List;
/**
* Created by mystery_code on 2018/7/10 0010.
* Description:
* Update:
*/
public class YearLineChart extends View {
private Line data;
public YearLineChart(Context context) {
this(context, null);
}
public YearLineChart(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public YearLineChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setColor(Color.parseColor("#333333"));
paint.setTextSize(DensityUtil.sp2px(13f));
paint.setAntiAlias(true);
axisThick = DensityUtil.dip2px(2f);
axisPaint = new Paint();
axisPaint.setAntiAlias(true);
axisPaint.setColor(Color.parseColor("#666666"));
axisPaint.setStrokeWidth(axisThick);
bgPaint = new Paint();
bgPaint.setAntiAlias(true);
bgPaint.setColor(Color.parseColor("#999999"));
linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(DensityUtil.dip2px(2f));
linePaint.setColor(Color.parseColor("#309dee"));
radius = disY = disX = DensityUtil.dip2px(4f);
}
private int width;
private int height;
private Paint paint;
private Paint axisPaint;
private Paint bgPaint;
private Paint linePaint;
private float axisThick;
private float radius;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.width = MeasureSpec.getSize(widthMeasureSpec);
this.height = MeasureSpec.getSize(heightMeasureSpec);
}
private Rect rect;
private int sH;
private int sW;
//字轴之间的距离
private int disX;
private int disY;
//z的坐标集合
private float[] axisX;
private float[] axisY;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (null == data) return;
String temp = "9999";
if (rect == null) rect = new Rect();
paint.getTextBounds(temp, 0, temp.length(), rect);
sW = rect.width();
sH = rect.height();
List y = data.getY();
List x = data.getX();
List z = data.getZ();
if (EmptyUtil.isList(x) || EmptyUtil.isList(y)) return;
if (axisX == null) axisX = new float[z.size()];
if (axisY == null) axisY = new float[z.size()];
//Y轴剩余高度
float retainH = height - sH * 3 - disY;
//Y轴元素距离
float unitY = retainH / (y.size() - 1);
//画轴所用的高度计算
float h = -unitY + 3 * sH / 2 + disY;
int w = sW + disX;
//X轴元素距离
float unitX = (width - 2 * (w)) / x.size();
//Y轴最大最小值
int max = find(y, 1);
int min = find(y, 0);
int minX = find(x, 0);
//单位Y坐标距离
float unitZ = retainH / (max - min);
//画单位
String unit = "/件";
canvas.drawText(unit, 0, unit.length(), sW, sH, paint);
//画Y轴线
canvas.drawLine(w, sH + disY, w, height - 3 * sH / 2 + axisThick / 2, axisPaint);
//画X轴线
canvas.drawLine(w, height - 3 * sH / 2, width, height - 3 * sH / 2, axisPaint);
//画Y轴
for (int i = 0; i < y.size(); i++) {
h += unitY;
String tempY = String.valueOf(y.get(i));
paint.getTextBounds(tempY, 0, tempY.length(), rect);
canvas.drawText(tempY, 0, tempY.length(), sW - rect.width(), h + sH / 2, paint);
//横线线
canvas.drawLine(w + disX, h, width, h, bgPaint);
// axisY[i]=retainH-(z.get(i).getCount()-min)*unitZ+3*sH/2+disY;
}
//x轴坐标插值
int dX = 0;
//画X轴
for (int i = 0; i < x.size(); i++) {
w += unitX;
if (i == 2) dX = x.get(i) - x.get(i - 1);
String tempX = String.valueOf(x.get(i));
paint.getTextBounds(tempX, 0, tempX.length(), rect);
canvas.drawText(tempX, 0, tempX.length(), w - rect.width() / 2, height, paint);
//竖线
canvas.drawLine(w, 3 * sH / 2 + disY, w, height - 3 * sH / 2 - disY, bgPaint);
}
//x轴单元插值
float uX = unitX / dX;
//画点
for (int i = 0; i < z.size(); i++) {
YearD yearD = z.get(i);
axisX[i] = (yearD.getYear() - minX) * uX + sW + disX + unitX;
LogUtil.e(yearD.getYear() + ">" + minX + ">" + uX + ">" + sW + ">" + disX + ">" + unitX);
axisY[i] = retainH - (z.get(i).getCount() - min) * unitZ + 3 * sH / 2 + disY;
canvas.drawCircle(axisX[i], axisY[i], radius, linePaint);
//画值
String tempZ = String.valueOf(yearD.getCount());
paint.getTextBounds(tempZ, 0, tempZ.length(), rect);
canvas.drawText(tempZ, 0, tempZ.length(), axisX[i] - rect.width(), axisY[i] - radius, paint);
//画折线
if (i != 0) canvas.drawLine(axisX[i - 1], axisY[i - 1], axisX[i], axisY[i], linePaint);
}
canvas.save();
}
private int find(List inch, int type) {
int num = 0;
for (int i = 0; i < inch.size(); i++) {
int count = inch.get(i);
if (i == 0) num = count;
if (0 == type) {
num = num < count ? num : count;
} else if (1 == type) {
num = num > count ? num : count;
}
}
return num;
}
public void setData(Line data) {
this.data = data;
invalidate();
}
// public class Line {
// private List x;
// private List y;
// private List z;
//
// public List getX() {
// return x;
// }
//
// public void setX(List x) {
// this.x = x;
// }
//
// public List getY() {
// return y;
// }
//
// public void setY(List y) {
// this.y = y;
// }
//
// public List getZ() {
// return z;
// }
//
// public void setZ(List z) {
// this.z = z;
// }
//
// public Line(List x, List y, List z) {
// this.x = x;
// this.y = y;
// this.z = z;
// }
// }
//public class YearD {
// private int year;
// private int count;
//
// public int getYear() {
// return year;
// }
//
// public void setYear(int year) {
// this.year = year;
// }
//
// public int getCount() {
// return count;
// }
//
// public void setCount(int count) {
// this.count = count;
// }
//
// public YearD(int year, int count) {
// this.year = year;
// this.count = count;
// }
//}
}
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import java.util.List;
/**
* Created by mystery_code on 2018/7/9 0009.
* Description:
* Update:
*/
public class PieChart extends View {
//文字绘制所需画笔
private Paint textPaint;
//圆弧绘制画笔
private Paint arcPaint;
//中心白圆画笔
private Paint innerPaint;
//外圆半径
private int outRadius;
//内圆半径
private int innerRadius;
//距离
private int dis;
//传入数据集合数据
private List list;
//首尾留白
private float top;
public PieChart(Context context) {
this(context, null);
}
public PieChart(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public PieChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
textPaint = new Paint();
textPaint.setAntiAlias(true);
arcPaint = new Paint();
arcPaint.setAntiAlias(true);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PieChart);
outRadius=ta.getDimensionPixelSize(R.styleable.PieChart_outRadius,80);
innerRadius=ta.getDimensionPixelSize(R.styleable.PieChart_innerRadius,50);
top=ta.getDimensionPixelSize(R.styleable.PieChart_padding,10);
int textSize=ta.getDimensionPixelSize(R.styleable.PieChart_pSize,13);
textPaint.setTextSize(textSize);
int lineThick = ta.getDimensionPixelSize(R.styleable.PieChart_lineThick, 1);
textPaint.setStrokeWidth(lineThick);
dis=innerRadius/2;
ta.recycle();
}
//给定的宽度和高度
private int width;
private int height;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.width=MeasureSpec.getSize(widthMeasureSpec);
this.height=MeasureSpec.getSize(heightMeasureSpec);
}
private int[] centerX;
private int[] centerY;
//画圆的区域
private RectF rectF ;
//测量计算使用
private Rect rect = new Rect();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (null == list || list.size() == 0) return;
//此处初始化的原因是控件在Activity的resume时会再次调用
//初始化角度:即所绘制饼图从Y轴开始
float currentAngle=-90;
//用于右侧数量展示(即右侧占比的份数)
int rightCount=0;
int size = list.size();
//**************整个坐标系平移了(因此坐标计算时需要考虑)************
canvas.translate(width / 2, height / 2);
if (centerX==null){
centerX = new int[size];
centerY = new int[size];
}
//圆饼图绘制区域
if (null==rectF){
rectF= new RectF(-outRadius, -outRadius, outRadius, outRadius);
}
//绘制圆弧
for (int i = 0; i < size; i++) {
PieEntity pieEntity = list.get(i);
//饼图区块颜色
int color = Color.parseColor("#" + pieEntity.getColor());
arcPaint.setColor(color);
//占比大小转化为角度度
float sweepAngle=pieEntity.getPercent() * 360;
//绘制圆弧
canvas.drawArc(rectF, currentAngle, sweepAngle, true, arcPaint);
//绘制圆弧的中点所在角度
float degree = currentAngle + pieEntity.getPercent() * 180;
//中点坐标计算
double radian = Math.toRadians(degree);
//Math函数的参数为弧度(弧度的cos值即为x轴坐标,sin值为Y轴坐标)
centerX[i] = (int) (outRadius * Math.cos(radian));
centerY[i] = (int) (outRadius * Math.sin(radian));
//绘制右侧说明计数
if (centerX[i] >0) rightCount++;
//记录已绘制圆弧的角度
currentAngle += sweepAngle;
}
//计算左侧占比份数
int leftCount=size-rightCount;
/**
* 文字的绘制机制可根据需求进行改良
*/
//计算绘制文字高度用以作为标准
String temp="标准";
textPaint.getTextBounds(temp, 0, temp.length(), rect);
//字体高度
int sH = rect.height();
//绘制文字说明的剩余高度
float retainH=width-2*top;
//右侧文字之间的间距(不是文字的中轴线间距)
float rightUnitDis=(retainH- sH *2*rightCount)/(rightCount-1);
//左侧文字之间的间距(同上)
float leftUnitDis=(retainH- sH *2*leftCount)/(leftCount-1);
//文字绘制的左侧或右侧高度的初始值(为了不干扰到第一个文字的绘制,左右此处减去了i=0时的距离)
float rightH=-width/2+top-rightUnitDis;
//*左侧的文字绘制从底部开始
float leftH=width/2-top+2*sH+leftUnitDis;
//绘制说明
for (int i=0;i0){
//文字高度累计值
rightH += (sH * 2+rightUnitDis);
float endX=centerX[i]+dis;
//绘制第一行文字
canvas.drawText(name, 0, name.length(), endX, rightH - sH, textPaint);
//绘制第二行文字(drawText不支持\n换行)
canvas.drawText(percent, 0, percent.length(), endX, rightH, textPaint);
//从弧线中点连接到文字中点(此处是两行文字所以stopY为rightH-sH)
canvas.drawLine(centerX[i], centerY[i], endX , rightH - sH, textPaint);
}else //左侧文字
if (centerX[i]<=0){
//同上
leftH-=(2* sH+leftUnitDis);
int length = name.length();
int length1 = percent.length();
if (length>length1) {
textPaint.getTextBounds(name, 0, name.length(), rect);
}else {
textPaint.getTextBounds(percent, 0, percent.length(), rect);
}
float endX=centerX[i]-dis-rect.width();
canvas.drawText(name, 0, name.length(), endX, leftH - sH, textPaint);
canvas.drawText(percent, 0, percent.length(), endX, leftH, textPaint);
canvas.drawLine(centerX[i], centerY[i], endX + rect.width() , leftH - sH, textPaint);
}
}
innerPaint = arcPaint;
//画中间的白色圆
innerPaint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawCircle(0, 0, innerRadius, innerPaint);
canvas.save();
}
public void setData(List list) {
this.list = list;
invalidate();
}
// 出入数据参考
// public class PieEntity {
// private String name;
// private float percent;
// private String color;
//
// public String getName() {
// return name;
// }
//
// public void setName(String name) {
// this.name = name;
// }
//
// public float getPercent() {
// return percent;
// }
//
// public void setPercent(float percent) {
// this.percent = percent;
// }
//
// public String getColor() {
// return color;
// }
//
// public void setColor(String color) {
// this.color = color;
// }
//
// public PieEntity(String name, float percent, String color) {
// this.name = name;
// this.percent = percent;
// this.color = color;
// }
// }
}
DensityUtil类(YearLineChart中自定义属性未提取,使用的是转化工具为默认值)
import android.content.res.Resources;
/**
* on 2016/8/13 15:00
* 作用:px和dp互相转换工具
*/
public class DensityUtil {
/**
* 根据手机的分辨率从 dip 的单位 转成为 px(像素)
*/
public static int dip2px(float dpValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(float pxValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*/
public static int sp2px(float spValue) {
final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
实例所需xml:
所需代码:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StatusBarUtil.transparent(this);
setContentView(R.layout.activity_main_1);
final List list=new ArrayList<>();
for (int i=0;i<10;i++) {
list.add(new YearEntity(String.valueOf(2000+i),new Random().nextInt(100)));
}
// final LineChart lc=findViewById(R.id.lc);
// lc.setClickEvent(new ClickEvent() {
// @Override
// public void click(int position) {
// Log.e(">>click>>",list.get(position).getYear());
// }
// });
// lc.setData(list);
LineChart lcs=findViewById(R.id.lcs);
lcs.setData(list);
lcs.setClickEvent(new LineChart.ClickEvent() {
@Override
public void click(int position) {
Log.e(">>click>>",list.get(position).getYear());
}
});
List pie=new ArrayList<>();
float sum=1f;
for (int i=0;i<10;i++) {
pie.add(new PieEntity(0.1 + "", 0.1f, color(i)));
}
PieChart pc=findViewById(R.id.pc);
pc.setData(pie);
int[] x=new int[7];
int[] y=new int[7];
int[] z=new int[7];
for (int i=x.length-1;i>=0;i--){
y[i]=(7-i)*10;
x[i]=2000+i;
z[i]=i*10;
}
YearLineChart ylc = findViewById(R.id.ylc);
ylc.setData(new Line(x,y,z));
}
private String color(int input){
switch (input%3){
case 0:return "022004";
case 1:return "000086";
case 2:return "ff2455";
}
return "ffffff";
}
}
希望能帮到有需要的人。