|
|
@@ -24,23 +24,33 @@ import java.util.List;
|
|
|
*/
|
|
|
@SuppressLint("NewApi")
|
|
|
public class FunnelView extends View implements ValueAnimator.AnimatorUpdateListener {
|
|
|
+
|
|
|
public static final float ANGLE_SCALE = 2.0f;
|
|
|
- private List<Integer> mMoneys = new ArrayList<>();
|
|
|
private int maxMoney;
|
|
|
private float phaseX = 1f;
|
|
|
private int textAlpha = 255;
|
|
|
- private ArrayList<Paint> mPaints = new ArrayList<>();
|
|
|
- private ArrayList<String> colors = new ArrayList<>();
|
|
|
+ private float mLastX;
|
|
|
+ private float mLastY;
|
|
|
+ private float mLastWidth;
|
|
|
+ private int maxHight;
|
|
|
+
|
|
|
private Paint mPaintLine;
|
|
|
private Paint mPaintText;
|
|
|
- private float mTotalHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
|
|
|
+ private ObjectAnimator xAnimator;
|
|
|
+ private ObjectAnimator alphaAnimator;
|
|
|
+ private List<Integer> mMoneys = new ArrayList<>();
|
|
|
+ private ArrayList<Paint> mPaints = new ArrayList<>();
|
|
|
+ private ArrayList<String> colors = new ArrayList<>();
|
|
|
+
|
|
|
private ArrayList<Float> mPathHeights = new ArrayList<>();
|
|
|
private ArrayList<Float> mPathAngleWidths = new ArrayList<>();
|
|
|
-
|
|
|
+
|
|
|
+ private float mTotalHeight =
|
|
|
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
|
|
|
private float maxWidth =
|
|
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 330, getResources().getDisplayMetrics());
|
|
|
private float maxLineH =
|
|
|
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
|
|
|
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, getResources().getDisplayMetrics());
|
|
|
private float minLineH =
|
|
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics());
|
|
|
|
|
|
@@ -53,12 +63,7 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
|
|
|
private float textStartOffsetX =
|
|
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 7, getResources().getDisplayMetrics());
|
|
|
-
|
|
|
- private float mLastX;
|
|
|
- private float mLastY;
|
|
|
- private float mLastWidth;
|
|
|
- private int maxHight;
|
|
|
-
|
|
|
+
|
|
|
public FunnelView(Context context) {
|
|
|
this(context, null);
|
|
|
}
|
|
|
@@ -71,21 +76,30 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
super(context, attrs, defStyleAttr);
|
|
|
init();
|
|
|
}
|
|
|
-
|
|
|
- public void setColors(ArrayList<String> colors) {
|
|
|
- this.colors = colors;
|
|
|
- }
|
|
|
-
|
|
|
- public void setData(List<Integer> moneys, int maxMoney,ArrayList<String> colors) {
|
|
|
+
|
|
|
+ public void setData(List<Integer> moneys, int maxMoney,ArrayList<String> colors) {
|
|
|
this.mMoneys = moneys;
|
|
|
this.maxMoney = maxMoney;
|
|
|
this.colors=colors;
|
|
|
+ stopAnimator();
|
|
|
init();
|
|
|
calculate();
|
|
|
+ getMaxHight();
|
|
|
requestLayout();
|
|
|
}
|
|
|
|
|
|
- private void calculate() {
|
|
|
+ private void getMaxHight() {
|
|
|
+ Log.i("FunnelMain2", JSON.toJSONString(mPathHeights));
|
|
|
+ for (int i=0;i<mMoneys.size();i++){
|
|
|
+ if (i==0) {
|
|
|
+ maxHight = (int) (startOffsetY + mPathHeights.get(i));
|
|
|
+ }else{
|
|
|
+ maxHight =(int)(maxHight+ mPathHeights.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void calculate() {
|
|
|
Log.i("Arison", "setData:moneys:" + JSON.toJSONString(mMoneys));
|
|
|
Log.i("Arison", "setData:maxMoney:" + maxMoney);
|
|
|
mPathHeights.clear();
|
|
|
@@ -99,16 +113,15 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
} else if (mPathHeight > maxLineH * phaseX) {
|
|
|
mPathHeight = maxLineH * phaseX;
|
|
|
}
|
|
|
- mPathHeights.add(i,mPathHeight);
|
|
|
+ mPathHeights.add(i, mPathHeight);
|
|
|
Float mPathAngleWidth = mPathHeight / ANGLE_SCALE;
|
|
|
- mPathAngleWidths.add(i,mPathAngleWidth);
|
|
|
+ mPathAngleWidths.add(i, mPathAngleWidth);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void init() {
|
|
|
mPaints.clear();
|
|
|
for (int i = 0; i < mMoneys.size(); i++) {
|
|
|
- Log.i("FunnelView", "init:" + i);
|
|
|
Paint mPaint = new Paint();
|
|
|
mPaint.setColor(Color.parseColor(colors.get(i)));
|
|
|
mPaint.setStyle(Paint.Style.FILL);
|
|
|
@@ -128,7 +141,7 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
mPaintText.setTextAlign(Paint.Align.LEFT);
|
|
|
}
|
|
|
|
|
|
- Path mPath;
|
|
|
+ private Path mPath;
|
|
|
|
|
|
private void draw2(Canvas canvas, Paint mPaint, Float mPathAngleWidth, Float mPathHeight,int i) {
|
|
|
if (i==0){
|
|
|
@@ -147,7 +160,8 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
mLastX = mLastX + mPathAngleWidth;
|
|
|
mLastY = mLastY + mPathHeight;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
protected void onDraw(Canvas canvas) {
|
|
|
@@ -155,23 +169,30 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
for (int i = 0; i < mMoneys.size(); i++) {
|
|
|
draw2(canvas, mPaints.get(i), mPathAngleWidths.get(i), mPathHeights.get(i),i);
|
|
|
}
|
|
|
- maxHight = Math.round(mLastY);
|
|
|
- // drawText9(canvas);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void animateY() {
|
|
|
- ObjectAnimator xAnimator = ObjectAnimator.ofFloat(this, "phaseX", 0, 1);
|
|
|
+ xAnimator = ObjectAnimator.ofFloat(this, "phaseX", 0, 1);
|
|
|
xAnimator.setDuration(2000);
|
|
|
xAnimator.addUpdateListener(this);
|
|
|
xAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
|
|
xAnimator.start();
|
|
|
|
|
|
- ObjectAnimator alphaAnimator = ObjectAnimator.ofInt(this, "textAlpha", 0, 255);
|
|
|
+ alphaAnimator = ObjectAnimator.ofInt(this, "textAlpha", 0, 255);
|
|
|
alphaAnimator.setDuration(2000);
|
|
|
alphaAnimator.addUpdateListener(this);
|
|
|
alphaAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
|
|
alphaAnimator.start();
|
|
|
}
|
|
|
+
|
|
|
+ private void stopAnimator(){
|
|
|
+ if (xAnimator!=null&&alphaAnimator!=null)
|
|
|
+ if (xAnimator.isRunning()) {
|
|
|
+ xAnimator.end();
|
|
|
+ alphaAnimator.end();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
|
@@ -179,8 +200,7 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true),
|
|
|
getMeasuredLength(heightMeasureSpec, false));
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
private int getMeasuredLength(int length, boolean isWidth) {
|
|
|
int specMode = MeasureSpec.getMode(length);
|
|
|
int specSize = MeasureSpec.getSize(length);
|
|
|
@@ -188,11 +208,8 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
if (specMode == MeasureSpec.EXACTLY) {
|
|
|
size = specSize;
|
|
|
} else {
|
|
|
-
|
|
|
- size = maxHight + 20;
|
|
|
- if (size<900)
|
|
|
- size=900;
|
|
|
- Log.i("Arison", "getMeasuredLength:size :" + size );
|
|
|
+ size = maxHight+(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
|
|
|
+ Log.i("FunnelMain", "onMeasure:"+ size);
|
|
|
}
|
|
|
return size;
|
|
|
}
|
|
|
@@ -213,21 +230,16 @@ public class FunnelView extends View implements ValueAnimator.AnimatorUpdateList
|
|
|
this.textAlpha = textAlpha;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
@Override
|
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
|
- calculate();
|
|
|
- postInvalidate();
|
|
|
+ Log.i("Animation", "onAnimationUpdate:动画更新...." );
|
|
|
+ calculate();
|
|
|
+ postInvalidate();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- private void drawText9(Canvas canvas) {
|
|
|
- Paint.FontMetrics fontMetrics = mPaintText.getFontMetrics();
|
|
|
- float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
|
|
|
- float offY = fontTotalHeight / 2 - fontMetrics.bottom;
|
|
|
- canvas.drawText("销售漏斗", mLastX + mLastWidth - mPathAngleWidths.get(mPathAngleWidths.size()-1) + 3 * textStartOffsetX, mLastY -
|
|
|
- mPathHeights.get(mPathHeights.size()-1) / 2 + offY, mPaintText);
|
|
|
+ @Override
|
|
|
+ protected void onAnimationEnd() {
|
|
|
+ super.onAnimationEnd();
|
|
|
+ Log.i("Animation", "onAnimationUpdate:动画结束....");
|
|
|
+ maxHight=0;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
+}
|