Android custom histogram with growth animation and click on the Bullet window effect demo_android

Source: Internet
Author: User
Tags drawtext

The project recently used a variety of charts, originally intended to use a third party, such as Mpandroid, this is a very powerful chart library, the application is very convenient, but finally found and design is not the same, no way, can only write their own. Today will be a written column of the demo posted here, the histogram can be based on the function of the data a few points:

1. According to the number of data, the dynamic plot of the pillars of the column chart;

2. Column chart each pillar of the drawing has a dynamic animation effect;

3. Each pillar has the Click event, when clicked Pop-up Prompt box, displays the related information, stipulated time, the pop-up window automatically disappears.

Okay, let's go ahead and show you the chart:

The following code is posted below:

Custom Column Chart classes:

Package Com.example.histogram; 
Import Android.content.Context; 
Import Android.graphics.Canvas; 
Import Android.graphics.Color; 
Import Android.graphics.Paint; 
Import Android.graphics.RectF; 
Import Android.os.Handler; 
Import Android.text.TextPaint; 
Import Android.util.AttributeSet; 
Import Android.util.Log; 
Import android.view.MotionEvent; 
Import Android.view.View; 
Import Com.example.histogram.UI.UI; 
Import Java.text.NumberFormat; 
 /** * Created by Zhangzdon 2016/6/16 0016. * Histogram/public class histogram extends View implements Runnable {private Handler Handler = new Handler (); New, realize animation private float animheight; Progress bar Animation height private Paint axislinepaint; Axis brushes private Paint hlinepaint; Internal horizontal dashed brush private Paint textpaint; Draw the text brush private Paint recpaint; Draws a histogram of the shadow background of a columnar chart private Paint datapaint; Draw the pen of the bar chart private Paint TextPaint2; Draw White text brush private Paint textPaint3; Draw the coordinates of the brush private Paint textPaint4; Draw the white vertical line on the x axis of the brush PRIVate string[] xtitlestring; X-axis scale private string[] ytitlestring; Y-axis scale private string[] data; The interface returns the Indicatordata used to compute the column height NumberFormat numberformat; Used to format the digital private float currentheight; The height of the current histogram should be computed by the private int num =-1; 
  How many columns to draw, because there are just boot data less than 24 of the case private float mrelativepxinheight; 
  private float mrelativepxinwidth; 
  Private Onchartclicklistener listener; 
  private int mdist; 
    public void setnum (int num) {this.num = num; 
  Invalidate (); 
    public void SetData (string[] data) {this.data = data; 
  Invalidate (); 
    public void Setxtitlestring (string[] title) {this.xtitlestring = title; 
  Invalidate (); 
  The public histogram {This (context, NULL); 
  Public histogram (context, AttributeSet attrs) {This (context, attrs, 0); 
  public void Settitle (string[] title) {this.xtitlestring = title; Public histogram, AttributeSet attrs, int defstyLEATTR) {Super (context, attrs, defstyleattr); 
  Init (context, attrs);  /** * For related initialization * @param context * @param attrs/private void init, AttributeSet 
    Attrs) {axislinepaint = new Paint (); 
    Hlinepaint = new Paint (); 
    Textpaint = new Paint (); 
    Recpaint = new Paint (); 
    Datapaint = new Paint (); 
    TextPaint2 = new Paint (); 
    TextPaint3 = new Paint (); 
    TextPaint4 = new Paint (); 
    NumberFormat = Numberformat.getnumberinstance (); Numberformat.setminimumfractiondigits (3); Set to retain three decimal axislinepaint.setcolor (Color.parsecolor ("#dbdde4") when printing; 
    Set the axis color to white Hlinepaint.setargb (51, 255, 255, 255); 
Textpaint.setcolor (Color.parsecolor ("#8593a1")); 
    Textpaint.settextsize (29); 
    Textpaint.settextsize (ui.dip2px (GetContext (), 12)); 
    Recpaint.setcolor (Color.parsecolor ("#f2f5fc")); 
    Datapaint.setcolor (Color.cyan); 
    Textpaint2.setcolor (Color.White); Textpaint2.settextsize (Ui.dip2PX (GetContext (), 12)); 
    Textpaint3.setcolor (Color.parsecolor ("#000000")); 
    Textpaint3.settextsize (ui.dip2px (GetContext (), 9)); 
    Textpaint4.setcolor (Color.parsecolor ("#8593a1")); 
    Textpaint4.settextsize (ui.dip2px (GetContext (), 6)); 
    Axislinepaint.setantialias (TRUE); 
    Hlinepaint.setantialias (TRUE); 
    Textpaint.setantialias (TRUE); 
    Recpaint.setantialias (TRUE); 
    Datapaint.setantialias (TRUE); 
    Textpaint2.setantialias (TRUE); 
    Textpaint3.setantialias (TRUE); 
  Textpaint4.setantialias (TRUE); 
    } @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); 
    if (data = null | | xtitlestring = NULL | | | num < 0) {return; 
    ///Draw Y-axis scale paint.fontmetrics metrics = textpaint3.getfontmetrics (); 
    int decent = (int) metrics.descent; 
    Float width = getwidth (); 
    float height = getheight (); 
    According to the prototype diagram, the relative dimensions of each px height in the figure mrelativepxinheight = height/470; According to the prototype diagram, the relative dimensions of each px width in the picture are shown in the actual figure MRElativepxinwidth = width/690; 
    Textpaint3.settextalign (Paint.Align.RIGHT); 
    Draw Ordinate ytitlestring = new string[6]; 
    YTITLESTRING[5] = "0"; 
    YTITLESTRING[4] = "20"; 
    YTITLESTRING[3] = "40"; 
    YTITLESTRING[2] = "60"; 
    YTITLESTRING[1] = "80"; 
    Ytitlestring[0] = "100"; for (int i = 0; i < ytitlestring.length i++) {canvas.drawtext (ytitlestring[i), Mrelativepxinwidth, (72 + 
    I *) * mrelativepxinheight + decent, textPaint3); 
    //Draw X-axis scale textpaint3.settextalign (Paint.Align.CENTER); 
    Textpaint4.settextalign (Paint.Align.CENTER); 
    Textpaint textpaint = new Textpaint (); 
    Textpaint.setcolor (Color.parsecolor ("#000000")); 
    Textpaint.settextsize (ui.dip2px (GetContext (), 9)); 
    Compute the spacing between columns//leftmost position mrelativepxinwidth, the rightmost position 630 epxinwidth, float totalwidth = 630-100; 
    The spacing between the pillar and the child is mdist = (int) (Totalwidth/(xtitlestring.length + 1)); for (int i = 0; i < xtitlestring.length; i++) {//Draw white vertical canvas.drawline ((i+1) * mdist) * mrelativepxinwidth, 348 * mrelativepxinheight, (100 + ( 
      i+1) * mdist) * mrelativepxinwidth, 352 * mrelativepxinheight, axislinepaint); Draw x-axis text Canvas.drawtext (Xtitlestring[i], (+ (i+1) * mdist) * mrelativepxinwidth, 370 * mrelativepxinheight, TE 
    XTPAINT3); 
//Draw Rectangle shadow for (int i = 0; i < num; i++) {RECTF RECTF = new RECTF (); 
Rectf.left = relativepxinwidth + i * relativepxinwidth; 
      Rectf.right = 121 * Relativepxinwidth + i * relativepxinwidth; 
      Rectf.left = Mrelativepxinwidth + (i+1) * mdist * mrelativepxinwidth; 
      Rectf.right = Mrelativepxinwidth + (i+1) * mdist * mrelativepxinwidth; 
      Rectf.top = Mrelativepxinheight; 
      Rectf.bottom = 338 * mrelativepxinheight; 
    Canvas.drawroundrect (RECTF, ten, recpaint); //Draw the X-axis coordinate for (int i = 0; i < 6; i++) {Canvas.drawline * MrelaTivepxinwidth, (+ i *) * mrelativepxinheight + decent, 630 * mrelativepxinwidth, (+ i *) * mrelativepxinheight 
    + decent, axislinepaint); //delay drawing to achieve animation effect. 
    The larger the number, the longer the delay, the slower the animation effect will be handler.postdelayed (this, 1); 
      for (int i = 0; i < num i++) {RECTF DATARECTF = new RECTF (); 
      Datarectf.left = Mrelativepxinwidth + (i + 1) * mdist * mrelativepxinwidth; 
      Datarectf.right = Mrelativepxinwidth + (i + 1) * mdist * mrelativepxinwidth; 
      Datapaint.setcolor (Color.parsecolor ("#3ac2d9")); 
      Get column Height currentheight = float.parsefloat (Data[num-1-i]); 
      if (Currentheight = = 0) {datarectf.top = 346 * mrelativepxinheight; 
      else if (currentheight = =) {datarectf.top = * mrelativepxinheight; else {if (animheight >= currentheight) {datarectf.top = 346 * Mrelativepxinheight-currentheig 
        HT/100 * 276 * mrelativepxinheight; else {DATARECTF. top = 346 * mRelativePxInHeight-276 * mrelativepxinheight * (animheight/100); 
} datarectf.bottom = 346 * mrelativepxinheight; Limit Maximum height if (Datarectf.top < mrelativepxinheight) {datarectf.top = * Mrelativepxinheig 
      Ht 
    Canvas.drawroundrect (DATARECTF, datapaint); 
    }//The animation effect of column growth @Override public void Run () {animheight = 1; 
    if (animheight >= 276 * mrelativepxinheight) {return; 
    else {invalidate (); @Override public boolean ontouchevent (Motionevent event) {switch (event.getaction ()) {Case Moti 
        Onevent.action_down: {//get click coordinate float x = Event.getx (); 
        Float y = event.gety (); 
        To judge the location of the click Point float leftx = 0; 
        float rightx = 0; for (int i = 0; i < num i++) {LEFTX = Mrelativepxinwidth + (i+ 1) * Mdist * Mrelativepxinwidth-mdis T/2 * MrelativepxinWidth; 
          RIGHTX = Mrelativepxinwidth + (i+ 1) * mdist * mrelativepxinwidth + MDIST/2 * mrelativepxinwidth; 
          if (x < LEFTX) {continue; } if (Leftx <= x && x <= rightx) {//Get the Y-value of the clicked column area float top = 346 * mRe 
            Lativepxinheight-float.parsefloat (Data[num-1-i])/276 * mrelativepxinheight; 
            Float bottom = 346 * mrelativepxinheight; if (y >= top && y <= bottom) {//Decide whether to set up the listening///will click on the first few pillars, click on the pillar at the tops of the Sit value for pop-up dialog hint data , also returns a percentage currentheidht = float.parsefloat (Data[num-1-i)) if (listener!= null) {LOG.E (" 
                SS "," X "+ x +"; y: "+ y); 
              Listener.onclick (i + 1, leftx + mdist/2,top,float.parsefloat (data[num-1-i))); 
            } break; 
      }} break; Case MOTIONEVENT.ACTION_MOVE:LOG.E ("Touch", "ACtion_move "); 
      Break 
        Case MOTIONEVENT.ACTION_UP:LOG.E ("Touch", "action_up"); 
    Break 
  return true; /** * Post click on the Listener interface/public interface Onchartclicklistener {void onClick (int num, float x, float y, F 
  Loat value); /** * Set pillar Click to monitor the method * @param listener/public void Setonchartclicklistener (Onchartclicklistener listen 
  ER) {this.listener = listener;  } 
}

Applications in XML files:

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= 
  "http://schemas.android.com/" Apk/res/android " 
  xmlns:tools=" Http://schemas.android.com/tools " 
  android:id=" @+id/activity_main 
  " Android:layout_width= "Match_parent" 
  android:layout_height= "match_parent" 
  android:orientation= "vertical" " 
  tools:context=" com.example.histogram.MainActivity "> 
  <textview 
    android:layout_width=" match _parent " 
    android:layout_height=" 40DP " 
    android:gravity=" center " 
    android:text=" busy indicator chart (%) 
    Android:textsize= "15SP" 
    android:textcolor= "#000000" 
    /> 
  <com.example.histogram.histogram 
    android:id= "@+id/staticview" 
    android:layout_width= "400DP" 
    android:layout_height= "500DP" 
    Android:layout_gravity= "Center_horizontal" 
    android:layout_marginbottom= "14DP" 
    android:layout_ margintop= "5DP"/> 

   implementation in activity:

Package Com.example.histogram; 
Import Android.os.Bundle; 
Import Android.os.Handler; 
Import android.support.v7.app.AppCompatActivity; 
Import Android.util.Log; 
Import Android.view.View; 
Import Android.widget.PopupWindow; 
Import Android.widget.TextView; 
  public class Mainactivity extends Appcompatactivity {private Popupwindow Mpopupwindow; 
    @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
    Setcontentview (R.layout.activity_main); 
    Final histogram histogram = (histogram) Findviewbyid (R.id.staticview); 
    string[] Data ={"100", "20", "40", "20", "80", "20", "60", "30", "5", "20", "60", "30", "5", "5", "20", "60", "30", "5"}; 
    Final string[] title = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "6", "7", "8", "9", "9", "6", "7", "8", "9"}; 
    Histogram.setnum (title.length); 
    Histogram.setdata (data); 
    Histogram.setxtitlestring (title); 
   Histogram.setonchartclicklistener (New Histogram.onchartclicklistener () {@Override   public void OnClick (int num, float x, float y, float value) {//Show hint window View inflate = view.inflate (Mai 
        Nactivity.this, R.layout.popupwindow, NULL); 
        TextView TextView = (TextView) Inflate.findviewbyid (R.ID.MAIN_TV); 
        Textview.settext (value + "%\n" + title[num-1]); 
        if (Mpopupwindow!= null) {Mpopupwindow.dismiss (); 
        } Mpopupwindow = new Popupwindow (inflate,140, true); 
        Mpopupwindow.settouchable (TRUE); 
            LOG.E ("ss", "num" + num +); X "+ x+"; y "+ y +"; value "+ Value +";(int) ((-histogram.getheight ()) + y-65) " 
        + (int) ((-histogram.getheight ()) + y-65) + "histogram.getheight ()" + histogram.getheight ());            Set the parameters and then show//Toast.maketext (mainactivity.this, "num" + num + "; x" + x+ "; y" + y + "; value" + Value// + ";p opupwindow.getwidth ()" + mpopupwindow.getwidth () + ";" 
        + Mpopupwindow.getheight (), Toast.length_short). Show (); MpopupwindoW.showasdropdown (histogram, (int) (X-65), (int) ((-histogram.getheight ()) + y-65)); 
        Mpopupwindow.setbackgrounddrawable (Getresources (). getdrawable (r.mipmap.databg_busyness)); 
          New Handler (). postdelayed (New Runnable () {public void run () {Mpopupwindow.dismiss (); 
      }, 1000); 
  } 
    });  } 
}

The above is a histogram of the Android custom with growth animation and click on the Bullet window tip effect. To achieve a simulated background data login effect, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.