android繪制折線圖繪制

rq300622 8年前發布 | 26K 次閱讀 Android開發 移動開發

折線圖的實現方法在github上有很多開源的程序,但是對于初學者來講,簡單一點的教程可能更容易入門,下面的文章來自csdn的陽光的小強,或許有用(沒仔細閱讀,大概看了下文章的結構清晰,折線圖的效果也還好)。

轉載自陽光的小強的博客http://blog.csdn.net/dawanganban/article/details/31445249

 

有時候我們在項目中會遇到使用折線圖等圖形,Android的開源項目中為我們提供了很多插件,但是很多時候我們需要根據具體項目自定義這些圖表,這一篇文章我們一起來看看如何在Android中使用Canvas繪制折線圖。先看看繪制的效果:

實現原理很簡單,我就直接給出代碼:

package com.example.testcanvasdraw; 
                                                                
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
                                                                
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.os.Handler; 
import android.os.Message; 
import android.util.AttributeSet; 
import android.view.View; 
                                                                
public class MyView extends View{ 
    private int XPoint = 60; 
    private int YPoint = 260; 
    private int XScale = 8;  //刻度長度 
    private int YScale = 40; 
    private int XLength = 380; 
    private int YLength = 240; 
                                                                    
    private int MaxDataSize = XLength / XScale; 
                                                                    
    private List<Integer> data = new ArrayList<Integer>(); 
                                                                    
                                                                
                                                                    
    private String[] YLabel = new String[YLength / YScale]; 
                                                                    
    private Handler handler = new Handler(){ 
        public void handleMessage(Message msg) { 
            if(msg.what == 0x1234){ 
                MyView.this.invalidate(); 
            } 
        }; 
    }; 
    public MyView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        for(int i=0; i<YLabel.length; i++){ 
            YLabel[i] = (i + 1) + "M/s"; 
        } 
                                                                        
        new Thread(new Runnable() { 
                                                                            
            @Override 
            public void run() { 
                while(true){ 
                    try { 
                        Thread.sleep(1000); 
                    } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                    } 
                    if(data.size() >= MaxDataSize){ 
                        data.remove(0); 
                    } 
                    data.add(new Random().nextInt(4) + 1); 
                    handler.sendEmptyMessage(0x1234); 
                } 
            } 
        }).start(); 
    } 
                                                                    
    @Override 
    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        Paint paint = new Paint(); 
        paint.setStyle(Paint.Style.STROKE); 
        paint.setAntiAlias(true); //去鋸齒 
        paint.setColor(Color.BLUE); 
                                                                        
        //畫Y軸 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint); 
                                                                        
        //Y軸箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint-YLength + 6, paint);  //箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint-YLength + 6 ,paint); 
                                                                        
        //添加刻度和文字 
        for(int i=0; i * YScale < YLength; i++) { 
            canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i * YScale, paint);  //刻度 
                                                                            
            canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);//文字 
        } 
                                                                        
        //畫X軸 
        canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint); 
        System.out.println("Data.size = " + data.size()); 
        if(data.size() > 1){ 
            for(int i=1; i<data.size(); i++){ 
                canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) * YScale,  
                        XPoint + i * XScale, YPoint - data.get(i) * YScale, paint); 
            } 
        } 
    } 
}

上面繪制折線部分我們還有一種方式同樣可以實現:

if(data.size() > 1){ 
    Path path = new Path(); 
    path.moveTo(XPoint, YPoint - data.get(0) * YScale); 
    for(int i=1; i<data.size(); i++){ 
        path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale); 
    } 
    canvas.drawPath(path, paint); 
}

下面我們將上面代碼修改,讓折線下面的區域顏色填充

package com.example.testcanvasdraw; 
                                           
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
                                           
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.os.Handler; 
import android.os.Message; 
import android.util.AttributeSet; 
import android.view.View; 
/**
 * 
 * @author 陽光小強
 * http://blog.csdn.net/dawanganban
 *
 */ 
public class MyView extends View { 
    private int XPoint = 60; 
    private int YPoint = 260; 
    private int XScale = 8; // 刻度長度 
    private int YScale = 40; 
    private int XLength = 380; 
    private int YLength = 240; 
                                           
    private int MaxDataSize = XLength / XScale; 
                                           
    private List<Integer> data = new ArrayList<Integer>(); 
                                           
    private String[] YLabel = new String[YLength / YScale]; 
                                           
    private Handler handler = new Handler() { 
        public void handleMessage(Message msg) { 
            if (msg.what == 0x1234) { 
                MyView.this.invalidate(); 
            } 
        }; 
    }; 
                                           
    public MyView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        for (int i = 0; i < YLabel.length; i++) { 
            YLabel[i] = (i + 1) + "M/s"; 
        } 
                                           
        new Thread(new Runnable() { 
                                           
            @Override 
            public void run() { 
                while (true) { 
                    try { 
                        Thread.sleep(1000); 
                    } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                    } 
                    if (data.size() >= MaxDataSize) { 
                        data.remove(0); 
                    } 
                    data.add(new Random().nextInt(4) + 1); 
                    handler.sendEmptyMessage(0x1234); 
                } 
            } 
        }).start(); 
    } 
                                           
    @Override 
    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        Paint paint = new Paint(); 
        paint.setStyle(Paint.Style.STROKE); 
        paint.setAntiAlias(true); // 去鋸齒 
        paint.setColor(Color.BLUE); 
                                           
        // 畫Y軸 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint); 
                                           
        // Y軸箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength 
                + 6, paint); // 箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength 
                + 6, paint); 
                                           
        // 添加刻度和文字 
        for (int i = 0; i * YScale < YLength; i++) { 
            canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i 
                    * YScale, paint); // 刻度 
                                           
            canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);// 文字 
        } 
                                           
        // 畫X軸 
        canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint); 
                                           
        // 繪折線 
        /*
         * if(data.size() > 1){ for(int i=1; i<data.size(); i++){
         * canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *
         * YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint); }
         * }
         */ 
        paint.setStyle(Paint.Style.FILL); 
        if (data.size() > 1) { 
            Path path = new Path(); 
            path.moveTo(XPoint, YPoint); 
            for (int i = 0; i < data.size(); i++) { 
                path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale); 
            } 
            path.lineTo(XPoint + (data.size() - 1) * XScale, YPoint); 
            canvas.drawPath(path, paint); 
        } 
    } 
}

上面的效果有時候還是達不到我們的要求,我們將代碼修改后效果如下:

package com.example.testcanvasdraw; 
                        
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
                        
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.os.Handler; 
import android.os.Message; 
import android.util.AttributeSet; 
import android.view.View; 
                        
/**
 * 
 * @author 陽光小強 http://blog.csdn.net/dawanganban
 * 
 */ 
public class MyView extends View { 
    private int XPoint = 60; 
    private int YPoint = 260; 
    private int XScale = 8; // 刻度長度 
    private int YScale = 40; 
    private int XLength = 380; 
    private int YLength = 240; 
                        
    private int MaxDataSize = XLength / XScale; 
                        
    private List<Integer> data = new ArrayList<Integer>(); 
                        
    private String[] YLabel = new String[YLength / YScale]; 
                        
    private Handler handler = new Handler() { 
        public void handleMessage(Message msg) { 
            if (msg.what == 0x1234) { 
                MyView.this.invalidate(); 
            } 
        }; 
    }; 
                        
    public MyView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        for (int i = 0; i < YLabel.length; i++) { 
            YLabel[i] = (i + 1) + "M/s"; 
        } 
                        
        new Thread(new Runnable() { 
                        
            @Override 
            public void run() { 
                while (true) { 
                    try { 
                        Thread.sleep(1000); 
                    } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                    } 
                    if (data.size() >= MaxDataSize) { 
                        data.remove(0); 
                    } 
                    data.add(new Random().nextInt(4) + 1); 
                    handler.sendEmptyMessage(0x1234); 
                } 
            } 
        }).start(); 
    } 
                        
    @Override 
    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        Paint paint = new Paint(); 
        paint.setStyle(Paint.Style.STROKE); 
        paint.setAntiAlias(true); // 去鋸齒 
        paint.setColor(Color.BLUE); 
                        
        // 畫Y軸 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint); 
                        
        // Y軸箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength 
                + 6, paint); // 箭頭 
        canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength 
                + 6, paint); 
                        
        // 添加刻度和文字 
        for (int i = 0; i * YScale < YLength; i++) { 
            canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i 
                    * YScale, paint); // 刻度 
                        
            canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);// 文字 
        } 
                        
        // 畫X軸 
        canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint); 
                        
        // 繪折線 
        /*
         * if(data.size() > 1){ for(int i=1; i<data.size(); i++){
         * canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *
         * YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint); }
         * }
         */ 
        paint.setColor(Color.RED); 
        paint.setStrokeWidth(5); 
                        
        Paint paint2 = new Paint(); 
        paint2.setColor(Color.BLUE); 
        paint2.setStyle(Paint.Style.FILL); 
        if (data.size() > 1) { 
            Path path = new Path(); 
            Path path2 = new Path(); 
            path.moveTo(XPoint, YPoint - data.get(0) * YScale); 
            path2.moveTo(XPoint, YPoint); 
            for (int i = 0; i < data.size(); i++) { 
                path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale); 
                path2.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale); 
            } 
            path2.lineTo(XPoint + (data.size() - 1) * XScale, YPoint); 
            canvas.drawPath(path, paint); 
            canvas.drawPath(path2, paint2); 
        } 
    } 
}

 

 本文由用戶 rq300622 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!