android自定义View,实现折线图(二)
2016-05-18 18:20
459 查看
效果图:
LineChartView类:
xml文件:
MainActivity:
下载资源传送门入口:
点击打开链接
LineChartView类:
public class LineChartView extends View { private int width; private int height; private float maxValue;//传入数据的最大值 private int dataNum;//数据总数 private Paint mPaintBg;//报表背景画笔 private Paint mPaintCoveredBg;//用于画数据覆盖部分 private Paint mPaintChartLine;//用于画报表的网格 private Paint mPaintDataLine;//用于画数据连线 private Paint mPaintTextDate;//用于画日期文本 private Paint mPaintCircle;//用于画空心圆 private Paint mPaintFilledCircle;//用于画实心圆 private Paint mPaintTextValue;//用于画数据访问量值 private Path path; private HashMap<Integer, PageViewData> dataTotal;//用于得存储传入的总数据 private float mRange[]=new float[3]; //传三个数值范围 public void setRange(float[] range) { mRange = range; } //用一个setPaints()方法,设定所有画笔的属性,增加代码灵活性 public void setPaints(int bgColor, int coveredBgColor, int chartLineColor , int dataLineColor, int textDateColor, int filledCircleColor, int circleColor, int textValueColor) { mPaintBg.setColor(bgColor); mPaintBg.setStyle(Paint.Style.FILL); mPaintCoveredBg.setColor(coveredBgColor); mPaintCoveredBg.setStyle(Paint.Style.FILL); mPaintCircle.setColor(circleColor); mPaintCircle.setStyle(Paint.Style.STROKE); mPaintCircle.setStrokeWidth(5); mPaintCircle.setAntiAlias(true); mPaintFilledCircle.setColor(filledCircleColor); mPaintFilledCircle.setStyle(Paint.Style.FILL); mPaintFilledCircle.setAntiAlias(true); mPaintChartLine.setColor(chartLineColor); mPaintChartLine.setStyle(Paint.Style.STROKE); mPaintChartLine.setAntiAlias(true); mPaintDataLine.setColor(dataLineColor); mPaintDataLine.setStyle(Paint.Style.STROKE); mPaintDataLine.setStrokeWidth(SizeConvert.dip2px(getContext(), 5)); mPaintDataLine.setAntiAlias(true); mPaintTextDate.setColor(textDateColor); mPaintTextDate.setTextSize(SizeConvert.dip2px(getContext(), 10)); mPaintTextDate.setTextAlign(Paint.Align.CENTER); mPaintTextDate.setAntiAlias(true); mPaintTextValue.setColor(textValueColor); mPaintTextValue.setTextSize(SizeConvert.dip2px(getContext(), 12)); mPaintTextValue.setTextAlign(Paint.Align.CENTER); mPaintTextValue.setAntiAlias(true); //重绘 invalidate(); } //用于设定传入的总数据 public void setDataTotal(HashMap<Integer, PageViewData> dataTotal) { this.dataTotal = dataTotal; invalidate(); } public LineChartView(Context context) { super(context); } public LineChartView(Context context, AttributeSet attrs) { super(context, attrs); mPaintBg = new Paint(); mPaintCoveredBg = new Paint(); mPaintCircle = new Paint(); mPaintChartLine = new Paint(); mPaintDataLine = new Paint(); mPaintTextDate = new Paint(); mPaintTextValue = new Paint(); mPaintFilledCircle = new Paint(); path = new Path(); dataTotal = new HashMap<>(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //当总数据已经传入,即不为空时,根据总数据中数据个数设定view的总宽 if (dataTotal != null) { width = (dataTotal.size() - 1) * xAddedNum + chartMarginHorizontal * 2; getMaxValue(dataTotal); } height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height); } /** * * 用于得到总数据中最大数据 * @param dataTotal 总数据 */ private void getMaxValue(HashMap<Integer, PageViewData> dataTotal) { maxValue = 0; dataNum = 0; for (int key : dataTotal.keySet()) { if (dataTotal.get(key).getPageViewValue() > maxValue) { maxValue = dataTotal.get(key).getPageViewValue(); } dataNum++; } } private int mChartHeight;//折线图的高 private int mChartWidth;//折线图的 private int startX = SizeConvert.dip2px(getContext(), 10);//开始绘制的x坐标 private int startY = SizeConvert.dip2px(getContext(), 5);//开始绘制的y坐标 private int chartMarginBottom = SizeConvert.dip2px(getContext(), 30);//折线图距离父控件底部距离 private int chartMarginHorizontal = SizeConvert.dip2px(getContext(), 12);//折线图距离父控件左右的距离 private int valueAlignLeft = SizeConvert.dip2px(getContext(), 0);//value参数文本距离左边距离 private int dateAlignLeft = SizeConvert.dip2px(getContext(), 0);//date参数文本距离左边距离 private int valueAlignBottom = SizeConvert.dip2px(getContext(), 5);//value参数文本距离底部距离 private int dateAlignBottom = SizeConvert.dip2px(getContext(), 10);//date参数文本距离底部距离 private int xAddedNum = SizeConvert.dip2px(getContext(), 60);//绘制折线图时每次移动的x轴距离 private int yAddedNum;//绘制折线图时每次移动的y轴距离 private boolean isDrawFirst;//是否是第一次绘制 private float circleFilledRadius = SizeConvert.dip2px(getContext(), 5);//外圆半径 private float circleRadius = SizeConvert.dip2px(getContext(), 3);//内圆半径 private float firstX;//第一个点的x轴坐标 private float firstY;//第一个点的y轴坐标 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); isDrawFirst = true; mChartHeight = height - chartMarginBottom; yAddedNum = mChartHeight / 4; mChartWidth = width - chartMarginHorizontal * 2; canvas.drawRect(startX, startY, startX + mChartWidth, startY + mChartHeight, mPaintBg); for (int key : dataTotal.keySet()) { float value = dataTotal.get(key).getPageViewValue(); if (isDrawFirst) { //当第一次绘制时得到第一个点的横纵坐标 firstX = startX; firstY = startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight; path.moveTo(firstX, firstY); isDrawFirst = false; } //每循环一次,将path线性相位一次 path.lineTo(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight); startX += xAddedNum; } //重新给startX赋值 startX = SizeConvert.dip2px(getContext(), 10); //画出折线 canvas.drawPath(path, mPaintDataLine); //画出折线以下部分的颜色 path.lineTo(startX + mChartWidth, startY + mChartHeight); path.lineTo(startX, startY + mChartHeight); path.lineTo(firstX, firstY); canvas.drawPath(path, mPaintCoveredBg); //画出每个点的圆圈,和对应的文本 for (int key : dataTotal.keySet()) { String date = dataTotal.get(key).getDate(); float value = dataTotal.get(key).getPageViewValue(); if(value <= mRange[0]){ mPaintCircle.setColor(Color.parseColor("#FF0000")); }else if(value >= mRange[2]) { mPaintCircle.setColor(Color.parseColor("#FBAD5F")); }else{ mPaintCircle.setColor(Color.parseColor("#C8E1A8")); } canvas.drawCircle(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight, circleFilledRadius, mPaintFilledCircle); canvas.drawCircle(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight, circleRadius, mPaintCircle); canvas.drawText(date + "", startX + dateAlignLeft, height - dateAlignBottom, mPaintTextDate); canvas.drawText(value + "", startX + valueAlignLeft, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight - valueAlignBottom, mPaintTextValue); startX += xAddedNum; } //在次使startX回到初始值 startX = SizeConvert.dip2px(getContext(), 10); /** * 画出网格 */ //竖线 for (int i = 0; i < dataNum; i++) { canvas.drawLine(startX + i * xAddedNum, startY, startX + i * xAddedNum, startY + mChartHeight, mPaintChartLine); } //横线 for (int i = 0; i < 5; i++) { canvas.drawLine(startX, startY + i * yAddedNum, startX + mChartWidth, startY + i * yAddedNum, mPaintChartLine); } path.reset(); } }
xml文件:
<HorizontalScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="none"> <com.xx.xx.LineChartView android:id="@+id/line_chart_view_item" android:layout_width="wrap_content" android:layout_height="160dp"/> </HorizontalScrollView>
MainActivity:
public class MainActivity extends Activity { private LineChartView mLineChartView; private HashMap<Integer,PageViewData> mDataPageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLineChartView = (LineChartView) findViewById(R.id.line_chart_view_item); initDataPageView(); } private void initDataPageView() { mDataPageView = new HashMap<>(); mDataPageView.put(1,new PageViewData(1,"5/1",4.0f)); mDataPageView.put(2,new PageViewData(2,"5/2",8.5f)); mDataPageView.put(3,new PageViewData(3,"5/3",5.4f)); mDataPageView.put(4,new PageViewData(4,"5/4",4.6f)); mDataPageView.put(5,new PageViewData(5,"5/5",6.2f)); mDataPageView.put(6,new PageViewData(6,"5/6",4.2f)); mDataPageView.put(7,new PageViewData(7,"5/7",10.4f)); mDataPageView.put(8,new PageViewData(8,"5/8",4.4f)); mDataPageView.put(9,new PageViewData(9,"5/9",5.5f)); mDataPageView.put(10,new PageViewData(10,"5/10",6.0f)); mDataPageView.put(11,new PageViewData(11,"5/11",5.4f)); mDataPageView.put(12,new PageViewData(12,"5/12",3.9f)); mDataPageView.put(13,new PageViewData(13,"5/13",4.2f)); mDataPageView.put(14,new PageViewData(14,"5/14",8.0f)); mDataPageView.put(15,new PageViewData(15,"5/15",11.4f)); mLineChartView.setDataTotal(mDataPageView); mLineChartView.setRange(new float[]{4.4f,7f,10f});//范围 mLineChartView.setPaints(Color.argb(255,225, 250, 250), Color.argb(255,234, 234, 250), Color.argb(255,74,208, 204), Color.argb(255,105, 210, 249),Color.argb(255,203, 203, 203) ,Color.argb(255,255, 255, 255),Color.argb(255,105, 210, 249),Color.argb(255,105, 210, 249)); }
下载资源传送门入口:
点击打开链接
相关文章推荐
- android中浮动菜单的基本实现
- Android 4层框架
- Android Notification通知栏的必备姿势
- android 跨应用程序广播发送接受
- Android Studio 中的 gradle 详解
- Android中getLocationOnScreen和getLocationInWindow
- 【Android进阶】Android 平滑图片加载和缓存库 Glide 使用详解
- Android 与 iOS 推送 Push Notification 的区别
- 65.Android 三大图片缓存原理、特性对比 (转)
- android activity之间传递bitmap
- Android Studio Gradle DSL method not found: 'android()' — Error(17,0)
- Android基础之drawable标签的使用下
- android:padding和android:margin的区别
- Android创建缓存文件并使用流读取
- android中sharedPreferences的用法
- [demo]仿IOS底部弹框效果及Android各类对话框和弹框效果
- 如何用studio将一个Android工程转成一个jar文件
- Android : 按 Back 按钮不返回处于后台的 Activity
- Android亮屏和熄屏控制
- Android 开发中Parcel存储类型和数据容器