转载请标明出处:http://blog.csdn.net/klxh2009/article/details/50879618
请先看效果:
废话不多说,直接上代码:
一、layout:activity_main
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.shenhua.linechart.MainActivity"
- tools:ignore="PxUsage,RtlHardcoded" >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:background="#11CD6E" >
- <Button
- android:id="@+id/button1"
- android:layout_width="35dp"
- android:layout_height="35dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:layout_marginLeft="10dp"
- android:background="@drawable/ic_menu" />
- <TextView
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginLeft="5dp"
- android:layout_toRightOf="@+id/button1"
- android:text="@string/app_name"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="@android:color/white" />
- <Button
- android:id="@+id/button2"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="10dp"
- android:background="@drawable/ic_setting" />
- <Button
- android:id="@+id/button3"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_centerVertical="true"
- android:layout_marginRight="10dp"
- android:layout_toLeftOf="@+id/button2"
- android:background="@drawable/ic_add" />
- </RelativeLayout>
- <com.shenhua.linechart.MyLineChart
- android:id="@+id/linechart"
- android:layout_marginTop="20dp"
- android:layout_width="fill_parent"
- android:layout_height="280px" />
- </LinearLayout>
二、attrs:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="MyLineChartView">
- <attr name="expend_color" format="color" />
- <attr name="income_color" format="color" />
- <attr name="table_color" format="color" />
- <attr name="tabletext_color" format="color" />
- </declare-styleable>
- </resources>
三、MyLineChart:
- package com.shenhua.linechart;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.Align;
- import android.graphics.Paint.Style;
- import android.graphics.PixelFormat;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- public class MyLineChart extends SurfaceView implements SurfaceHolder.Callback {
- private SurfaceHolder sfh;
- public static int right; // 坐标系右边距离框架左边的距离(由activity计算得出)
- public static int gapX; // 两根竖线间的间隙(由activity计算得出)
- private boolean isRunning = true;
- private static float[] Percent_Expend = { 60, 32.5f, 46, 0, 0, 70, 55, 100,
- 57, 10.2f, 30, 10 };// 12个支出百分比
- private static float[] Percent_Income = { 0, 0, 0, 88, 0, 25, 30, 10, 57,
- 88.2f, 30, 0 };// 12个收入百分比
- private static String[] Percent = { "0", "10", "20", "30", "40", "50",
- "60", "70", "80", "90", "100" };// 每个月支出的金额占全年总支出的百分比
- private String[] houres = { "1", "2", "3", "4", "5", "6", "7", "8", "9",
- "10", "11", "12 (月份)" };// 一年的12个月
- private int tick = 10; // 时间间隔(ms)
- private int each_width = 20; // 两根横线间的间隙
- private int top = 10; // 坐标系顶部距离框架顶端框的距离
- private int bottom = top + each_width * 10;// 坐标系地段距离框架顶端的距离top+gapy*10=210
- private int left = 40; // 坐标系左边距离框架左边框的距离
- private int currentX;
- private int oldX;
- private String title_expend = "• 每月支出金额占全年支出百分比";
- private String title_income = "• 每月收入金额占全年收入百分比";
- private int mExpendColor;
- private int mIncomeColor;
- private int mTableColor;
- private int mTableTextColor;
- public MyLineChart(Context context) {
- super(context);
- }
- public MyLineChart(Context context, AttributeSet atr) {
- super(context, atr);
- setZOrderOnTop(true);
- sfh = this.getHolder();
- sfh.addCallback(this);
- sfh.setFormat(PixelFormat.TRANSLUCENT);
- TypedArray typedArray = context.getTheme().obtainStyledAttributes(atr,
- R.styleable.MyLineChartView, 0, 0);
- mExpendColor = typedArray.getColor(
- R.styleable.MyLineChartView_expend_color, Color.RED);
- mIncomeColor = typedArray
- .getColor(R.styleable.MyLineChartView_income_color,
- Color.rgb(0, 185, 99));
- mTableColor = typedArray
- .getColor(R.styleable.MyLineChartView_table_color,
- Color.rgb(0, 214, 251));
- mTableTextColor = typedArray.getColor(
- R.styleable.MyLineChartView_tabletext_color, Color.BLUE);
- typedArray.recycle();
- }
- /**
- * @see android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder)
- */
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- isRunning = true;
- currentX = 0;
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- gridDraw();
- drawChartLine();
- }
- });
- thread.start();
- }
- @Override
- public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder arg0) {
- isRunning = false;
- }
- protected void gridDraw() {
- Canvas canvas = sfh.lockCanvas();
- Paint mTablePaint = new Paint();
- mTablePaint.setColor(mTableColor);
- mTablePaint.setAntiAlias(true);
- mTablePaint.setStrokeWidth(1);
- mTablePaint.setStyle(Style.FILL);
- Paint mTableTextPaint = new Paint();
- mTableTextPaint.setAntiAlias(true);
- mTableTextPaint.setColor(mTableTextColor);
- mTableTextPaint.setTextSize(12f);
- Paint mExpendPaint = new Paint();
- mExpendPaint.setColor(mExpendColor);
- mExpendPaint.setTextSize(16f);
- Paint mIncomePaint = new Paint();
- mIncomePaint.setColor(mIncomeColor);
- mIncomePaint.setTextSize(16f);
- // 绘制坐标系
- for (int i = 0; i < 11; i++) {
- canvas.drawLine(left, top + each_width * i, left + gapX * 11, top
- + each_width * i, mTablePaint);
- mTableTextPaint.setTextAlign(Align.RIGHT);
- canvas.drawText("" + Percent[i], left - 2, bottom + 3 - 20 * i,
- mTableTextPaint);
- }
- for (int i = 0; i < 12; i++) {
- canvas.drawLine(left + gapX * i, top, left + gapX * i, bottom,
- mTablePaint);
- mTableTextPaint.setTextAlign(Align.CENTER);
- canvas.drawText(houres[i], left + gapX * i, bottom + 14,
- mTableTextPaint);
- }
- Rect mBound_expend = new Rect();
- mExpendPaint.getTextBounds(title_expend, 0, title_expend.length(),
- mBound_expend);
- canvas.drawText(title_expend, getWidth() / 2 - mBound_expend.width()
- / 2, bottom + 40, mExpendPaint);
- Rect mBound_income = new Rect();
- mIncomePaint.getTextBounds(title_income, 0, title_income.length(),
- mBound_income);
- canvas.drawText(title_income, getWidth() / 2 - mBound_income.width()
- / 2, bottom + 60, mIncomePaint);
- sfh.unlockCanvasAndPost(canvas);
- }
- private void drawChartLine() {
- while (isRunning) {
- try {
- drawChart(currentX);
- currentX++;
- try {
- Thread.sleep(tick);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } catch (Exception e) {
- System.out.println("绘制出错!");
- }
- }
- }
- void drawChart(int length) {
- if (length == 0)
- oldX = 0;
- Canvas canvas = sfh.lockCanvas(new Rect(oldX, 0, oldX + length,
- bottom + 30));
- drawExpend(canvas);
- drawIncome(canvas);
- sfh.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像
- }
- private void drawIncome(Canvas canvas) {
- Paint mPointPaint = new Paint();
- mPointPaint.setAntiAlias(true);
- mPointPaint.setColor(mIncomeColor);
- Paint mLinePaint = new Paint();
- mLinePaint.setColor(mIncomeColor);
- mLinePaint.setAntiAlias(true);
- mLinePaint.setStrokeWidth(2);
- mLinePaint.setStyle(Style.FILL);
- float cx = 0f;
- float cy = 0f;
- float dx = 0f;
- float dy = 0f;
- for (int j = 0; j < Percent_Income.length - 1; j++) {
- cx = left + gapX * j;
- cy = bottom - (Percent_Income[j] * 0.1f) * each_width;
- dx = left + gapX * (j + 1);
- dy = bottom - (Percent_Income[j + 1] * 0.1f) * each_width;
- canvas.drawCircle(cx, cy, 3, mPointPaint);
- canvas.drawLine(cx, cy, dx, dy, mLinePaint);
- }
- }
- private void drawExpend(Canvas canvas) {
- Paint mPointPaint = new Paint();
- mPointPaint.setAntiAlias(true);
- mPointPaint.setColor(mExpendColor);
- Paint mLinePaint = new Paint();
- mLinePaint.setColor(mExpendColor);
- mLinePaint.setAntiAlias(true);
- mLinePaint.setStrokeWidth(2);
- mLinePaint.setStyle(Style.FILL);
- float cx = 0f;
- float cy = 0f;
- float dx = 0f;
- float dy = 0f;
- for (int j = 0; j < Percent_Expend.length - 1; j++) {
- cx = left + gapX * j;
- cy = bottom - (Percent_Expend[j] * 0.1f) * each_width;
- dx = left + gapX * (j + 1);
- dy = bottom - (Percent_Expend[j + 1] * 0.1f) * each_width;
- canvas.drawCircle(cx, cy, 3, mPointPaint);
- canvas.drawLine(cx, cy, dx, dy, mLinePaint);
- }
- }
- }
四、MainActivity:
- package com.shenhua.linechart;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.DisplayMetrics;
- import android.util.Log;
- import android.view.Window;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- DisplayMetrics dm = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(dm);
- int width = dm.widthPixels;
- int height = dm.heightPixels;
- Log.d("系统信息", "该设备的分辨是:" + width + "*" + height);
- MyLineChart.right = width - 35;
- MyLineChart.gapX = (width - 70) / 11;
- }
- }
附上 GitHub Demo:https://github.com/shenhuanet/LineChart