android 自定义折线图

来源:互联网 发布:英语四级真题推荐知乎 编辑:程序博客网 时间:2024/06/06 01:09



 

注意:不要以为获取到了控件所在位置设置下就可以让控件在具体的位置了,而是所在布局文件类型以,0,0开始,所有

不要去设置位置默认就在那个位置,设置了反而让控件不在本身正确的位置了



一:填充+透明方法

填充paint.setStyle(Paint.Style.FILL); 

透明paint.setARGB(90, 0, 255, 255);    



二:折线处标点

在画折线的相同坐标位置画上一个图片

 canvas.drawBitmap(bitmap_point,
               XPoint+(i) * XScale - bitmap_point.getWidth() / 2,
               YPoint - data.get(i) * YScale - bitmap_point.getHeight() / 2, null);//绘制折线转折处的点


三:具体代码

[html] view plain copy
  1. public class PanelLnChart extends View {  
  2.       
  3.       
  4.     private Context contextgb;  
  5.       
  6.     private int XPoint ;  
  7.     private int YPoint;  
  8.     private int XScale ;// 刻度长度   
  9.     private int YScale ;   
  10.     private int XLength ;   
  11.     private int YLength ;   
  12.                                               
  13.     private int MaxDataSize;   
  14.                                               
  15.     private List<Integer> data = new ArrayList<Integer>();   
  16.                                               
  17.     private String[] YLabel ; //总长度除以每个刻度的长度来技术有多少个刻度 是很科学的   
  18.     private String[] XLabel ;     
  19.       
  20.     private Handler handler = new Handler() {   
  21.         public void handleMessage(Message msg) {   
  22.             if (msg.what == 0x1234) {   
  23.                 PanelLnChart.this.invalidate();   
  24.             }   
  25.         };   
  26.     };   
  27.                       
  28.     public static int Dp2Px(Context fagb,float dp) {   
  29.           
  30.         final float scale = fagb.getResources().getDisplayMetrics().density;     
  31.         return (int) (dp * scale + 0.5f);     
  32.      }  
  33.       
  34.     public PanelLnChart(Context context)  
  35.     {  
  36.          this(context, null);  
  37.     }  
  38.       
  39.     public PanelLnChart(Context context, AttributeSet attrs) {   
  40.       
  41.         super(context,attrs);           
  42.         contextgb = context;  
  43.         super.setBackgroundColor(Color.parseColor("#f6f6f6"));           
  44.          
  45.         XScale = Dp2Px(context, 42); // 刻度长度   
  46.          YScale =  Dp2Px(context, 30);   
  47.          XLength = Dp2Px(context, 294);   
  48.          YLength = Dp2Px(context, 210);   
  49.            
  50.          MaxDataSize = XLength / XScale;   
  51.          YLabel = new String[YLength / YScale]; //总长度除以每个刻度的长度来技术有多少个刻度 是很科学的   
  52.          XLabel = new String[XLength / XScale];     
  53.            
  54.      
  55.           
  56.         for (int i = 0; i < YLabel.length; i++) {   
  57.             YLabel[i] = (i + 1) + "T";   
  58.         }   
  59.         for (int i = 0; i < XLabel.length; i++) {   
  60.             XLabel[i] = (i + 1) + ".00";   
  61.         }   
  62.           
  63.           
  64.           
  65.         data.add(4);   
  66.         data.add(3);   
  67.         data.add(5);   
  68.         data.add(3);   
  69.         data.add(2);   
  70.         data.add(3);   
  71.         data.add(2);   
  72.         handler.sendEmptyMessage(0x1234);   
  73.                                               
  74.         /*new Thread(new Runnable() {   
  75.                                               
  76.             @Override   
  77.             public void run() {   
  78.                 while (true) {   
  79.                     try {   
  80.                         Thread.sleep(1000);   
  81.                     } catch (InterruptedException e) {   
  82.                         e.printStackTrace();   
  83.                     }   
  84.                     if (data.size() >= MaxDataSize) {   
  85.                         data.remove(0);   
  86.                     }   
  87.                     data.add(new Random().nextInt(4) + 1);   
  88.                     handler.sendEmptyMessage(0x1234);   
  89.                 }   
  90.             }   
  91.         }).start(); */  
  92.     }   
  93.                                               
  94.     @Override   
  95.     protected void onDraw(Canvas canvas) {   
  96.         super.onDraw(canvas);   
  97.           
  98.         System.out.println(" 得到的高度:"+getHeight()+" 得到的宽度:"+getWidth());  
  99.           
  100.         int[] location = new  int[2] ;  
  101.         getLocationOnScreen(location);//获取在整个屏幕内的绝对坐标    
  102.         System.out.println("OnScreen x:"+location[0]+" y:"+location[1]);    
  103.           
  104.         //(0,0)表示控件当前所在布局文件的位置  
  105.         XPoint =  Dp2Px(contextgb, 15); //需要留一个文字显示的位置    
  106.         YPoint =  0+YLength;//需要加一下y的高度  
  107.          
  108.         Paint paint = new Paint();   
  109.         paint.setStyle(Paint.Style.STROKE);   
  110.         paint.setAntiAlias(true); // 去锯齿   
  111.         //paint.setAlpha(20);//透明度  
  112.           
  113.         Shader mShader = new LinearGradient(0, 0, 0, getHeight(), new int[] {  
  114.             Color.argb(30, 0, 255, 255), Color.argb(30, 0, 255, 255),  
  115.             Color.argb(30, 0, 255, 255) }, null, Shader.TileMode.CLAMP); //图表背景颜色  
  116.         paint.setStrokeWidth(2f);  
  117.         paint.setShader(mShader);                 
  118.         //paint.setColor(0xff00ffff);                                                
  119.         // 画Y轴   
  120.          
  121.              
  122.           
  123.         Paint paintkd = new Paint();   
  124.         paintkd.setStyle(Paint.Style.STROKE);   
  125.         paintkd.setAntiAlias(true); // 去锯齿   
  126.         paintkd.setColor(Color.parseColor("#e6e6e6"));   
  127.           
  128.           
  129.         Paint paintkfont = new Paint();   
  130.         paintkfont.setStyle(Paint.Style.STROKE);   
  131.         paintkfont.setAntiAlias(true); // 去锯齿   
  132.         paintkfont.setTextSize(Dp2Px(contextgb, 15));  
  133.         paintkfont.setColor(Color.parseColor("#6fb2de"));   
  134.           
  135.         //画Y轴   
  136.         canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paintkd);  
  137.       /*  // Y轴箭头   
  138.         canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength   
  139.                 + 6, paint); // 箭头   
  140.         canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength   
  141.                 + 6, paint); */  
  142.                                               
  143.         //纵坐标  添加刻度和文字   
  144.         for (int i = 0; (i+1) * YScale <= YLength; i++) {  //这里(i+1)是为了处理高度和刻度长度除不尽的情况                 
  145.               
  146.           
  147.                 canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + XLength, YPoint - i   
  148.                         * YScale, paintkd); //横线,横向刻度   
  149.                                                                                   
  150.                 canvas.drawText(YLabel[i], XPoint - Dp2Px(contextgb, 17), YPoint - i * YScale, paintkfont);// 文字   
  151.         }     
  152.           
  153.           
  154.         //x轴刻度  
  155.         for(int i=0;i<XLength/XScale;i++)  
  156.         {             
  157.             canvas.drawLine(XPoint+i*XScale, YPoint, XPoint+i*XScale, YPoint-YLength, paintkd); //竖线      
  158.             if(i>0)//第一个坐标位置不显示(坐标原点)  
  159.             {                 
  160.                 //减去这个是因为要减去文字的长度让他居中 Dp2Px(AJlearnCharts.this,15)  
  161.                 canvas.drawText(XLabel[i],XPoint+i*XScale- Dp2Px(contextgb,15),YPoint, paintkfont);// 文字  
  162.             }  
  163.         }  
  164.                                               
  165.         // 画X轴   
  166.         canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paintkd);   
  167.                                               
  168.           
  169.         Bitmap bitmap_point = BitmapFactory.decodeResource(getResources(),  
  170.                 R.drawable.icon_point_blues);  
  171.           
  172.         //绘制填充  
  173.         paint.setStyle(Paint.Style.FILL);   
  174.                                                       
  175.         if (data.size() > 1) {   
  176.             Path path = new Path();   
  177.               
  178.             path.moveTo(XPoint, YPoint);//设置起点坐标   
  179.             for (int i = 0; i < data.size(); i++) {   
  180.                 path.lineTo(XPoint+(i) * XScale, YPoint - data.get(i) * YScale);  
  181.                   
  182.                 canvas.drawBitmap(bitmap_point,  
  183.                         XPoint+(i) * XScale - bitmap_point.getWidth() / 2,  
  184.                         YPoint - data.get(i) * YScale - bitmap_point.getHeight() / 2, null);//绘制折线转折处的点  
  185.             }   
  186.             path.lineTo(XPoint + (data.size() - 1) * XScale, YPoint);//最后一个刻度封闭起来   
  187.             canvas.drawPath(path, paint);   
  188.         }             
  189.         drawzhexian(canvas);  
  190.     }    
  191.           
  192.     //绘折线无填充的线,重叠绘制一次就可以让折线不同颜色,重叠后的效果      
  193.     private void drawzhexian(Canvas canvas)  
  194.     {  
  195.         Resources res = getResources();  
  196.          float  tb = res.getDimension(R.dimen.historyscore_tb);  
  197.           
  198.         Paint paint_brokenLine = new Paint();  
  199.         paint_brokenLine.setStrokeWidth(tb * 0.1f);  
  200.         paint_brokenLine.setColor(0xff00ffff);  
  201.         paint_brokenLine.setAntiAlias(true);  
  202.           
  203.           
  204.          if(data.size() > 1){ for(int i=1; i<data.size(); i++){  
  205.               canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *  
  206.               YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint_brokenLine); }  
  207.          }  
  208.     }  
  209.       
  210. }  



四:使用自定义的控件

[html] view plain copy
  1. <LinearLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="wrap_content"  
  4.     android:id="@+id/oil_reportfrom_id"   
  5.     android:background="#f0f0f0"  
  6.        android:layout_marginTop="6dp"  
  7.     android:layout_marginLeft="10dp"  
  8.     android:layout_marginRight="10dp"  
  9.     android:orientation="vertical"  
  10.     >  
  11.            
  12.     <com.lc.mycontrol.PanelLnChart  
  13.          android:layout_width="match_parent"  
  14.          android:layout_height="215dp"  
  15.         />          
  16. </LinearLayout>   

这里使用Android:layout_width="match_parent"是可以的,但是高度还是要自己设定一个值


 

注意:不要以为获取到了控件所在位置设置下就可以让控件在具体的位置了,而是所在布局文件类型以,0,0开始,所有

不要去设置位置默认就在那个位置,设置了反而让控件不在本身正确的位置了



一:填充+透明方法

填充paint.setStyle(Paint.Style.FILL); 

透明paint.setARGB(90, 0, 255, 255);    



二:折线处标点

在画折线的相同坐标位置画上一个图片

 canvas.drawBitmap(bitmap_point,
               XPoint+(i) * XScale - bitmap_point.getWidth() / 2,
               YPoint - data.get(i) * YScale - bitmap_point.getHeight() / 2, null);//绘制折线转折处的点


三:具体代码

[html] view plain copy
  1. public class PanelLnChart extends View {  
  2.       
  3.       
  4.     private Context contextgb;  
  5.       
  6.     private int XPoint ;  
  7.     private int YPoint;  
  8.     private int XScale ;// 刻度长度   
  9.     private int YScale ;   
  10.     private int XLength ;   
  11.     private int YLength ;   
  12.                                               
  13.     private int MaxDataSize;   
  14.                                               
  15.     private List<Integer> data = new ArrayList<Integer>();   
  16.                                               
  17.     private String[] YLabel ; //总长度除以每个刻度的长度来技术有多少个刻度 是很科学的   
  18.     private String[] XLabel ;     
  19.       
  20.     private Handler handler = new Handler() {   
  21.         public void handleMessage(Message msg) {   
  22.             if (msg.what == 0x1234) {   
  23.                 PanelLnChart.this.invalidate();   
  24.             }   
  25.         };   
  26.     };   
  27.                       
  28.     public static int Dp2Px(Context fagb,float dp) {   
  29.           
  30.         final float scale = fagb.getResources().getDisplayMetrics().density;     
  31.         return (int) (dp * scale + 0.5f);     
  32.      }  
  33.       
  34.     public PanelLnChart(Context context)  
  35.     {  
  36.          this(context, null);  
  37.     }  
  38.       
  39.     public PanelLnChart(Context context, AttributeSet attrs) {   
  40.       
  41.         super(context,attrs);           
  42.         contextgb = context;  
  43.         super.setBackgroundColor(Color.parseColor("#f6f6f6"));           
  44.          
  45.         XScale = Dp2Px(context, 42); // 刻度长度   
  46.          YScale =  Dp2Px(context, 30);   
  47.          XLength = Dp2Px(context, 294);   
  48.          YLength = Dp2Px(context, 210);   
  49.            
  50.          MaxDataSize = XLength / XScale;   
  51.          YLabel = new String[YLength / YScale]; //总长度除以每个刻度的长度来技术有多少个刻度 是很科学的   
  52.          XLabel = new String[XLength / XScale];     
  53.            
  54.      
  55.           
  56.         for (int i = 0; i < YLabel.length; i++) {   
  57.             YLabel[i] = (i + 1) + "T";   
  58.         }   
  59.         for (int i = 0; i < XLabel.length; i++) {   
  60.             XLabel[i] = (i + 1) + ".00";   
  61.         }   
  62.           
  63.           
  64.           
  65.         data.add(4);   
  66.         data.add(3);   
  67.         data.add(5);   
  68.         data.add(3);   
  69.         data.add(2);   
  70.         data.add(3);   
  71.         data.add(2);   
  72.         handler.sendEmptyMessage(0x1234);   
  73.                                               
  74.         /*new Thread(new Runnable() {   
  75.                                               
  76.             @Override   
  77.             public void run() {   
  78.                 while (true) {   
  79.                     try {   
  80.                         Thread.sleep(1000);   
  81.                     } catch (InterruptedException e) {   
  82.                         e.printStackTrace();   
  83.                     }   
  84.                     if (data.size() >= MaxDataSize) {   
  85.                         data.remove(0);   
  86.                     }   
  87.                     data.add(new Random().nextInt(4) + 1);   
  88.                     handler.sendEmptyMessage(0x1234);   
  89.                 }   
  90.             }   
  91.         }).start(); */  
  92.     }   
  93.                                               
  94.     @Override   
  95.     protected void onDraw(Canvas canvas) {   
  96.         super.onDraw(canvas);   
  97.           
  98.         System.out.println(" 得到的高度:"+getHeight()+" 得到的宽度:"+getWidth());  
  99.           
  100.         int[] location = new  int[2] ;  
  101.         getLocationOnScreen(location);//获取在整个屏幕内的绝对坐标    
  102.         System.out.println("OnScreen x:"+location[0]+" y:"+location[1]);    
  103.           
  104.         //(0,0)表示控件当前所在布局文件的位置  
  105.         XPoint =  Dp2Px(contextgb, 15); //需要留一个文字显示的位置    
  106.         YPoint =  0+YLength;//需要加一下y的高度  
  107.          
  108.         Paint paint = new Paint();   
  109.         paint.setStyle(Paint.Style.STROKE);   
  110.         paint.setAntiAlias(true); // 去锯齿   
  111.         //paint.setAlpha(20);//透明度  
  112.           
  113.         Shader mShader = new LinearGradient(0, 0, 0, getHeight(), new int[] {  
  114.             Color.argb(30, 0, 255, 255), Color.argb(30, 0, 255, 255),  
  115.             Color.argb(30, 0, 255, 255) }, null, Shader.TileMode.CLAMP); //图表背景颜色  
  116.         paint.setStrokeWidth(2f);  
  117.         paint.setShader(mShader);                 
  118.         //paint.setColor(0xff00ffff);                                                
  119.         // 画Y轴   
  120.          
  121.              
  122.           
  123.         Paint paintkd = new Paint();   
  124.         paintkd.setStyle(Paint.Style.STROKE);   
  125.         paintkd.setAntiAlias(true); // 去锯齿   
  126.         paintkd.setColor(Color.parseColor("#e6e6e6"));   
  127.           
  128.           
  129.         Paint paintkfont = new Paint();   
  130.         paintkfont.setStyle(Paint.Style.STROKE);   
  131.         paintkfont.setAntiAlias(true); // 去锯齿   
  132.         paintkfont.setTextSize(Dp2Px(contextgb, 15));  
  133.         paintkfont.setColor(Color.parseColor("#6fb2de"));   
  134.           
  135.         //画Y轴   
  136.         canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paintkd);  
  137.       /*  // Y轴箭头   
  138.         canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength   
  139.                 + 6, paint); // 箭头   
  140.         canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength   
  141.                 + 6, paint); */  
  142.                                               
  143.         //纵坐标  添加刻度和文字   
  144.         for (int i = 0; (i+1) * YScale <= YLength; i++) {  //这里(i+1)是为了处理高度和刻度长度除不尽的情况                 
  145.               
  146.           
  147.                 canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + XLength, YPoint - i   
  148.                         * YScale, paintkd); //横线,横向刻度   
  149.                                                                                   
  150.                 canvas.drawText(YLabel[i], XPoint - Dp2Px(contextgb, 17), YPoint - i * YScale, paintkfont);// 文字   
  151.         }     
  152.           
  153.           
  154.         //x轴刻度  
  155.         for(int i=0;i<XLength/XScale;i++)  
  156.         {             
  157.             canvas.drawLine(XPoint+i*XScale, YPoint, XPoint+i*XScale, YPoint-YLength, paintkd); //竖线      
  158.             if(i>0)//第一个坐标位置不显示(坐标原点)  
  159.             {                 
  160.                 //减去这个是因为要减去文字的长度让他居中 Dp2Px(AJlearnCharts.this,15)  
  161.                 canvas.drawText(XLabel[i],XPoint+i*XScale- Dp2Px(contextgb,15),YPoint, paintkfont);// 文字  
  162.             }  
  163.         }  
  164.                                               
  165.         // 画X轴   
  166.         canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paintkd);   
  167.                                               
  168.           
  169.         Bitmap bitmap_point = BitmapFactory.decodeResource(getResources(),  
  170.                 R.drawable.icon_point_blues);  
  171.           
  172.         //绘制填充  
  173.         paint.setStyle(Paint.Style.FILL);   
  174.                                                       
  175.         if (data.size() > 1) {   
  176.             Path path = new Path();   
  177.               
  178.             path.moveTo(XPoint, YPoint);//设置起点坐标   
  179.             for (int i = 0; i < data.size(); i++) {   
  180.                 path.lineTo(XPoint+(i) * XScale, YPoint - data.get(i) * YScale);  
  181.                   
  182.                 canvas.drawBitmap(bitmap_point,  
  183.                         XPoint+(i) * XScale - bitmap_point.getWidth() / 2,  
  184.                         YPoint - data.get(i) * YScale - bitmap_point.getHeight() / 2, null);//绘制折线转折处的点  
  185.             }   
  186.             path.lineTo(XPoint + (data.size() - 1) * XScale, YPoint);//最后一个刻度封闭起来   
  187.             canvas.drawPath(path, paint);   
  188.         }             
  189.         drawzhexian(canvas);  
  190.     }    
  191.           
  192.     //绘折线无填充的线,重叠绘制一次就可以让折线不同颜色,重叠后的效果      
  193.     private void drawzhexian(Canvas canvas)  
  194.     {  
  195.         Resources res = getResources();  
  196.          float  tb = res.getDimension(R.dimen.historyscore_tb);  
  197.           
  198.         Paint paint_brokenLine = new Paint();  
  199.         paint_brokenLine.setStrokeWidth(tb * 0.1f);  
  200.         paint_brokenLine.setColor(0xff00ffff);  
  201.         paint_brokenLine.setAntiAlias(true);  
  202.           
  203.           
  204.          if(data.size() > 1){ for(int i=1; i<data.size(); i++){  
  205.               canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *  
  206.               YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint_brokenLine); }  
  207.          }  
  208.     }  
  209.       
  210. }  



四:使用自定义的控件

[html] view plain copy
  1. <LinearLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="wrap_content"  
  4.     android:id="@+id/oil_reportfrom_id"   
  5.     android:background="#f0f0f0"  
  6.        android:layout_marginTop="6dp"  
  7.     android:layout_marginLeft="10dp"  
  8.     android:layout_marginRight="10dp"  
  9.     android:orientation="vertical"  
  10.     >  
  11.            
  12.     <com.lc.mycontrol.PanelLnChart  
  13.          android:layout_width="match_parent"  
  14.          android:layout_height="215dp"  
  15.         />          
  16. </LinearLayout>   

这里使用Android:layout_width="match_parent"是可以的,但是高度还是要自己设定一个值