基于上次静态漏斗图做出改进:
- 动态添加数据,根据集合数据动态展示;
- 高度根据漏斗图数据自适配,根据数据量多少,漏斗图高度自动适配;
- 顺利添加动画效果;
- 各种手机型号自适配;
- 加文字,加线条等需要的人士,参考早期版本;
- 代码示例改日上传到github上;
- 代码地址:FunnelView
有任何问题可以加本博客的qq群交流;
效果展示:
核心代码(完整代码见github):
public void setData(List<Integer> moneys, int maxMoney,ArrayList<String> colors) { this.mMoneys = moneys; this.maxMoney = maxMoney; this.colors=colors;
//初始化的时候需要停止来不及关闭的动画,引发不想看到的bug;
stopAnimator();
init();
calculate();
//提前算好填充数据的最大高度,这是关键;
//此方法不能放在onMeasure方法中进行测量 getMaxHight();
requestLayout();
}
private void stopAnimator(){ if (xAnimator!=null&&alphaAnimator!=null) if (xAnimator.isRunning()) { xAnimator.end(); alphaAnimator.end(); } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false)); } private int getMeasuredLength(int length, boolean isWidth) { int specMode = MeasureSpec.getMode(length); int specSize = MeasureSpec.getSize(length); int size; if (specMode == MeasureSpec.EXACTLY) { size = specSize; } else { size = maxHight+(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()); Log.i("FunnelMain", "onMeasure:"+ size); } return size; }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < mMoneys.size(); i++) { draw2(canvas, mPaints.get(i), mPathAngleWidths.get(i), mPathHeights.get(i),i); } }
ObjectAnimator xAnimator; ObjectAnimator alphaAnimator; public void animateY() { xAnimator = ObjectAnimator.ofFloat(this, "phaseX", 0, 1); xAnimator.setDuration(2000); xAnimator.addUpdateListener(this); xAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); xAnimator.start(); alphaAnimator = ObjectAnimator.ofInt(this, "textAlpha", 0, 255); alphaAnimator.setDuration(2000); alphaAnimator.addUpdateListener(this); alphaAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); alphaAnimator.start(); }
private void calculate() { mPathHeights.clear(); mPathAngleWidths.clear(); for (int i = 0; i < mMoneys.size(); i++) { int money = mMoneys.get(i); float scale = (float) money / maxMoney; Float mPathHeight = mTotalHeight * scale * phaseX; if (mPathHeight < minLineH * phaseX) { mPathHeight = minLineH * phaseX; } else if (mPathHeight > maxLineH * phaseX) { mPathHeight = maxLineH * phaseX; } mPathHeights.add(i, mPathHeight); Float mPathAngleWidth = mPathHeight / ANGLE_SCALE; mPathAngleWidths.add(i, mPathAngleWidth); } }