版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qingfeng812/article/details/52356259
基于上次静态漏斗图做出改进:
- 动态添加数据,根据集合数据动态展示;
- 高度根据漏斗图数据自适配,根据数据量多少,漏斗图高度自动适配;
- 顺利添加动画效果;
- 各种手机型号自适配;
- 加文字,加线条等需要的人士,参考早期版本;
- 代码示例改日上传到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);
}
}