Android自定义带增长动画和点击d窗提示效果的柱状图DEMO

Android自定义带增长动画和点击d窗提示效果的柱状图DEMO,第1张

概述项目中最近用到各种图表,本来打算用第三方的,例如MPAndroid,这是一个十分强大的图表库,应用起来十分方便,但是最终发现和设计不太一样,没办法,只能自己写了。今天将写好的柱状图的demo贴在这,该柱状图可根据数

项目中最近用到各种图表,本来打算用第三方的,例如MPAndroID,这是一个十分强大的图表库,应用起来十分方便,但是最终发现和设计不太一样,没办法,只能自己写了。今天将写好的柱状图的demo贴在这,该柱状图可根据数据的功能有一下几点:

     1. 根据数据的多少,动态的绘制柱状图柱子的条数;

     2. 柱状图每条柱子的绘制都有动态的动画效果;

     3. 每条柱子有点击事件,点击时d出提示框,显示相关信息,规定时间后,d窗自动消失。

     好了,先上演示图:

     下边贴出相关代码:

     自定义柱状图类:

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.  * 柱状图  */ public class HistoGram extends VIEw implements Runnable {   private Handler handler = new Handler(); // 用于延时更新,实现动画   private float animHeight; // 进度条动画高度   private Paint axislinePaint; // 坐标轴画笔   private Paint hlinePaint; // 内部水平虚线画笔   private Paint textPaint; // 绘制文本的画笔   private Paint recPaint; // 绘制柱状图阴影背景的画笔   private Paint dataPaint; // 绘制柱状图的画笔   private Paint textPaint2; // 绘制白色文本的画笔   private Paint textPaint3; // 绘制坐标的画笔   private Paint textPaint4; // 绘制x轴上的白色竖线的画笔   private String[] xTitleString; // x轴刻度   private String[] yTitleString; // y轴刻度   private String[] data; // 接口返回的indicatordata,用于计算柱子高度   NumberFormat numberFormat; //用于格式化数字   private float currentHeight; // 当前柱状图应有的高度,应由计算得来   private int num = -1; // 画多少条柱子,因为存在刚开机数据不足24条的情况   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();   }   public HistoGram(Context context) {     this(context,null);   }   public HistoGram(Context context,AttributeSet attrs) {     this(context,attrs,0);   }   public voID setTitle(String[] Title) {     this.xTitleString = Title;   }   public HistoGram(Context context,AttributeSet attrs,int defStyleAttr) {     super(context,defStyleAttr);     init(context,attrs);   }   /**    * 进行相关初始化 *** 作    * @param context    * @param attrs    */   private voID init(Context context,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); //设置打印时保留三位小数     axislinePaint.setcolor(color.parsecolor("#dbdde4")); //设置坐标轴的颜色为白色     hlinePaint.setARGB(51,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;     }     //绘制y轴刻度     Paint.FontMetrics metrics = textPaint3.getFontMetrics();     int decent = (int) metrics.descent;     float wIDth = getWIDth();     float height = getHeight();     //根据原型图得出,图中每px高度在实际中的相对尺寸     mrelativePxInHeight = height / 470;     //根据原型图得出,图中每px宽度在实际中的相对尺寸     mrelativePxInWIDth = wIDth / 690;     textPaint3.setTextAlign(Paint.Align.RIGHT);     //绘制纵坐标     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],88 * mrelativePxInWIDth,(72 + i * 56) * mrelativePxInHeight + decent,textPaint3);     }     //绘制x轴刻度     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));     //计算柱子之间的间隔     //最左侧位置100 * mrelativePxInWIDth,最右侧位置630 ePxInWIDth,float totalWIDth = 630 - 100;     // 柱子与之子之间的间隔     mdist = (int) (totalWIDth / (xTitleString.length + 1));     for (int i = 0; i < xTitleString.length; i++) {       //绘制白色竖线       canvas.drawline((100 + (i+1) * mdist) * mrelativePxInWIDth,348 * mrelativePxInHeight,(100 + (i+1) * mdist) * mrelativePxInWIDth,352 * mrelativePxInHeight,axislinePaint);       //绘制x轴文字       canvas.drawText(xTitleString[i],370 * mrelativePxInHeight,textPaint3);     } //    绘制矩形阴影     for (int i = 0; i < num; i++) {       RectF rectF = new RectF(); //      rectF.left = 111 * relativePxInWIDth + i * 22 * relativePxInWIDth; //      rectF.right = 121 * relativePxInWIDth + i * 22 * relativePxInWIDth;       rectF.left = 95 * mrelativePxInWIDth + (i+1) * mdist * mrelativePxInWIDth;       rectF.right = 105 * mrelativePxInWIDth +(i+1) * mdist * mrelativePxInWIDth;       rectF.top = 70 * mrelativePxInHeight;       rectF.bottom = 338 * mrelativePxInHeight;       canvas.drawRoundRect(rectF,10,recPaint);     }     //    绘制x轴坐标线     for (int i = 0; i < 6; i++) {       canvas.drawline(100 * mrelativePxInWIDth,(66 + i * 56) * mrelativePxInHeight + decent,630 * mrelativePxInWIDth,axislinePaint);     } //    延时绘制,实现动画效果。数字越大,延时越久,动画效果就会越慢     handler.postDelayed(this,1);     for (int i = 0; i < num; i++) {       RectF dataRectF = new RectF();       dataRectF.left = 95 * mrelativePxInWIDth + (i + 1) * mdist * mrelativePxInWIDth;       dataRectF.right = 105 * mrelativePxInWIDth + (i + 1) * mdist * mrelativePxInWIDth;       dataPaint.setcolor(color.parsecolor("#3ac2d9"));       //获取柱子高度       currentHeight = float.parsefloat(data[num - 1 - i]);       if (currentHeight == 0) {         dataRectF.top = 346 * mrelativePxInHeight;       } else if (currentHeight == 100) {         dataRectF.top = 70 * mrelativePxInHeight;       } else {         if (animHeight >= currentHeight) {           dataRectF.top = 346 * mrelativePxInHeight - currentHeight / 100 * 276 * mrelativePxInHeight;         } else {           dataRectF.top = 346 * mrelativePxInHeight - 276 * mrelativePxInHeight * (animHeight / 100);         }       }       dataRectF.bottom = 346 * mrelativePxInHeight; //        限制最高高度       if (dataRectF.top < 70 * mrelativePxInHeight) {         dataRectF.top = 70 * mrelativePxInHeight;       }       canvas.drawRoundRect(dataRectF,dataPaint);     }   }   //实现柱子增长的动画效果   @OverrIDe   public voID run() {     animHeight += 1;     if (animHeight >= 276 * mrelativePxInHeight) {       return;     } else {       invalIDate();     }   }   @OverrIDe   public boolean ontouchEvent(MotionEvent event) {     switch (event.getAction()) {       case MotionEvent.ACTION_DOWN: {         //获取点击坐标         float x = event.getX();         float y = event.getY();         //判断点击点的位置         float leftx = 0;         float rightx = 0;         for (int i = 0; i < num; i++) {           leftx = 95 * mrelativePxInWIDth + (i+ 1) * mdist * mrelativePxInWIDth - mdist/2 * mrelativePxInWIDth;           rightx = 105 * mrelativePxInWIDth + (i+ 1) * mdist * mrelativePxInWIDth + mdist/2 * mrelativePxInWIDth;           if (x < leftx) {             continue;           }           if (leftx <= x && x <= rightx) {             //获取点击的柱子区域的y值             float top = 346 * mrelativePxInHeight - float.parsefloat(data[num - 1 - i])/ 100 * 276 * mrelativePxInHeight;             float bottom = 346 * mrelativePxInHeight;             if (y >= top && y <= bottom) {               //判断是否设置监听               //将点击的第几条柱子,点击柱子顶部的坐值,用于d出dialog提示数据,还要返回百分比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;   }   /**    * 柱子点击时的监听接口    */   public interface OnChartClickListener {     voID onClick(int num,float x,float y,float value);   }   /**    * 设置柱子点击监听的方法    * @param Listener    */   public voID setonChartClickListener(OnChartClickListener Listener) {     this.Listener = Listener;   } } 

  在xml文件中的应用:

<?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="繁忙度指示图(%)"     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"/> </linearLayout> 

   在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","80","60","30","5","5"};     final String[] Title = {"1","2","3","4","6","7","8","9","9"};     histoGram.setNum(Title.length);     histoGram.setData(data);     histoGram.setxTitleString(Title);     histoGram.setonChartClickListener(new HistoGram.OnChartClickListener() {       @OverrIDe       public voID onClick(int num,float value) {         //显示提示窗         VIEw inflate = VIEw.inflate(MainActivity.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,60,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());         // 设置好参数之后再show //        Toast.makeText(MainActivity.this,"num" + num +";x" + x+";y"+ y + ";value" + value //            +";popupWindow.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);       }     });   } } 

以上所述是小编给大家介绍的AndroID自定义带增长动画和点击d窗提示效果的柱状图,实现一个模拟后台数据登入的效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android自定义带增长动画和点击d窗提示效果的柱状图DEMO全部内容,希望文章能够帮你解决Android自定义带增长动画和点击d窗提示效果的柱状图DEMO所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1147764.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存