天天看點

Android 自定義漏鬥圖FunnelView(二)

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

繼續閱讀