android 漏斗 动画,android 漏斗图

效果图

b84357b9a019

漏斗图效果

核心代码

自定义View:FunnelChart

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.RectF;

import android.util.ArrayMap;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

/**

* Created by benz on 2020/12/22.

*/

public class FunnelChart extends View {

private static final int SPACE = 3;

private ArrayList mPaths = new ArrayList<>();

private ArrayList mPaints = new ArrayList<>();

private List mData;

private OnValueTouchListener mTouchListener;

public FunnelChart(Context context) {

this(context, null);

}

public FunnelChart(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public FunnelChart(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

public void setTouchListener(OnValueTouchListener touchListener) {

mTouchListener = touchListener;

}

public void renderData(List data) {

if (data == null || data.isEmpty()) {

return;

}

mData = data;

mPaints.clear();

for (int i = 0; i < mData.size(); i++) {

Paint mPaint = new Paint();

mPaint.setColor(mData.get(i).color);

mPaint.setStyle(Paint.Style.FILL);

mPaint.setDither(true);

mPaint.setAntiAlias(true);

mPaints.add(mPaint);

}

invalidate();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (mData == null || mData.isEmpty()) {

Paint p = new Paint();

p.setColor(Color.parseColor("#ffffff"));

p.setStyle(Paint.Style.FILL);

p.setDither(true);

p.setAntiAlias(true);

canvas.drawPaint(p);

canvas.save();

return;

}

mPaths.clear();

float lastX = 0;

float lastY = 0;

float value1 = mData.get(0).value;

for (int i = 0; i < mData.size(); i++) {

Path mPath = new Path();

mPath.moveTo(lastX, lastY);

mPath.lineTo(lastX + mData.get(i).value * 1f / value1 * getWidth(), lastY);

if (i < mData.size() - 1) {

float value2 = mData.get(i + 1).value;

mPath.lineTo(getWidth() / 2f + value2 / value1 * getWidth() / 2f, getHeight() * 1f / mData.size() * (i + 1) - SPACE);

mPath.lineTo(getWidth() / 2f - value2 / value1 * getWidth() / 2f, getHeight() * 1f / mData.size() * (i + 1) - SPACE);

lastX = getWidth() / 2f - value2 / value1 * getWidth() / 2f;

} else {

mPath.lineTo(getWidth() / 2f, getHeight() * 1f / mData.size() * (i + 1) - SPACE);

mPath.lineTo(getWidth() / 2f, getHeight() * 1f / mData.size() * (i + 1) - SPACE);

lastX = getWidth() / 2f;

}

mPath.close();

mPaths.add(mPath);

lastY = getHeight() * 1f / mData.size() * (i + 1) + SPACE;

canvas.drawPath(mPaths.get(i), mPaints.get(i));

}

canvas.save();

}

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

return super.dispatchTouchEvent(event);//默认实现,可以不写

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (mTouchListener != null) {

float x = event.getX();

float y = event.getY();

for (int i = 0; i < mPaths.size(); i++) {

Path path = mPaths.get(i);

RectF rectF = new RectF();

path.computeBounds(rectF, true);

if (rectF.contains(x, y)) {

mTouchListener.onValueTouch(mData.get(i));

break;

}

}

return true;

} else {

return super.onTouchEvent(event);

}

}

public interface OnValueTouchListener{

void onValueTouch(FunnelData funnelData);

}

}

自定义数据结构:FunnelData

/**

* Created by benz on 2020/12/22.

*/

public class FunnelData {

public float value;

public int color;

}

如何使用

import android.graphics.Color;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

public class MainActivity extends AppCompatActivity {

FunnelChart funnelView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

funnelView = (FunnelChart) findViewById(R.id.funnelview);

funnelView.setTouchListener(new FunnelChart.OnValueTouchListener() {

@Override

public void onValueTouch(FunnelData funnelData) {

Toast.makeText(MainActivity.this, "点击了" + funnelData.value, Toast.LENGTH_SHORT).show();

}

});

List data = new ArrayList<>();

int size = 3;

for (int i = 0; i < size; i++) {

FunnelData funnelData = new FunnelData();

funnelData.color = Color.parseColor(getRandColorCode());

funnelData.value = getRandomNumber(1000 / (i + 1), 800 / (i + 1));

data.add(funnelData);

}

funnelView.renderData(data);

}

private int getRandomNumber(int max, int min) {

Random random = new Random();

return random.nextInt(max) % (max - min + 1) + min;

}

private String getRandColorCode() {

String r, g, b;

Random random = new Random();

r = Integer.toHexString(random.nextInt(256)).toUpperCase();

g = Integer.toHexString(random.nextInt(256)).toUpperCase();

b = Integer.toHexString(random.nextInt(256)).toUpperCase();

r = r.length() == 1 ? "0" + r : r;

g = g.length() == 1 ? "0" + g : g;

b = b.length() == 1 ? "0" + b : b;

return "#" + r + g + b;

}

}

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#C0C1C2">

android:id="@+id/funnelview"

android:layout_width="300dp"

android:layout_height="200dp"

android:layout_centerInParent="true"

android:background="#ffffff" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值