版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 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);
}
}