关于MPChart图例过多而无法全部显示的问题

关于Android图表MPChart库的图例过多无法全部显示的问题

当时自己在用MPChart库做项目的时候遇到的这样一个问题,饼状图的图例实在太多,MPChart所提供的功能无法显示全部的图例(最多也就十几个),柱状图和线图图例不是很多,就是这个饼图的需求有些不一样。然后就在MPChart库里面一直找有没有能动态显示图例的方法,然后就gg了,找半天也没有。最后还是自己写一个吧。

具体代码:

public class LegendView extends LinearLayout {
    public static final int HORIZONTAL_TOP = 0; //横向头部
    public static final int HORIZONTAL_BOTTOM = 1;//横向底部
    public static final int VERTICAL_LEFT = 2;//纵向左侧
    public static final int VERTICAL_RIGHT = 3;//纵向右侧

    private int direction;//方向
    private int leftOffset = 10;//图例列表左侧间距
    private int topOffset = 120;//图例列表上侧间距
    private int rightOffset = 10;//图例列表右侧间距
    private int bottomOffset = 120;//图例列表下侧间距
    private Context context;
    private View chart;
    private LegendViewAdapter adapter;
    private RecyclerView recyclerView;

    public LegendView(Context context, int direction, View chart) {
        super(context, null);
        this.direction = direction;
        this.context = context;
        this.chart = chart;
    }

    private void initView() {
        setOrientation(VERTICAL);
        setBackgroundResource(R.color.transparent);
        RelativeLayout rootView = new RelativeLayout(getContext());
        recyclerView = new RecyclerView(getContext());
        recyclerView.setId(Integer.MAX_VALUE - 1000);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        RelativeLayout.LayoutParams chartLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        chartLayoutParams.setMargins(leftOffset,topOffset,rightOffset,bottomOffset);
        if (direction == HORIZONTAL_TOP || direction == HORIZONTAL_BOTTOM) {
            recyclerView.setHorizontalScrollBarEnabled(false);
            recyclerView.setVerticalScrollBarEnabled(true);
            recyclerView.setFocusable(true);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            if (direction == HORIZONTAL_TOP) {
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                chartLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, recyclerView.getId());
            } else {
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                chartLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, recyclerView.getId());
            }
            linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setLayoutParams(layoutParams);
        } else {
            recyclerView.setHorizontalScrollBarEnabled(true);
            recyclerView.setVerticalScrollBarEnabled(false);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
            if (direction == VERTICAL_LEFT) {
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                chartLayoutParams.addRule(RelativeLayout.RIGHT_OF, recyclerView.getId());
            } else {
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                chartLayoutParams.addRule(RelativeLayout.LEFT_OF, recyclerView.getId());
            }
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setLayoutParams(layoutParams);
        }
        recyclerView.setOverScrollMode(OVER_SCROLL_NEVER);
        recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                rv.getParent().getParent().requestDisallowInterceptTouchEvent(true);
                return false;
            }

            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {

            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

            }
        });
        chart.setLayoutParams(chartLayoutParams);
        rootView.addView(chart);
        rootView.addView(recyclerView);
        addView(rootView);
    }
    public void initData(List legendEntity) {
        initView();
        adapter = new LegendViewAdapter();
        recyclerView.setAdapter(adapter);
        adapter.setDatas(legendEntity);
    }
    public void setOffset(int leftOffset, int topOffset, int rightOffset, int bottomOffset) {
        this.leftOffset = leftOffset;
        this.topOffset = topOffset;
        this.rightOffset = rightOffset;
        this.bottomOffset = bottomOffset;
    }
}

这么长一串代码看着确实有点多,不需要看懂直接建个类复制进去就行。下面说一下这个类怎么用:

LegendView pieView = new LegendView(pieChart.getContext(), legendDirection, view);//初始化对象,这个view参数是饼状图对象
pieView.setOffset(leftOffset, topOffset, rightOffset, bottomOffset);//设置各个方向的偏移
List legendEntities = new ArrayList<>();
for (int i = 0; i < pieItemList.size(); i++) {//配置每一个图例的属性值,pieItemList是图例名称集合
    LegendEntity legendEntity = new LegendEntity();
    legendEntity.legend = pieItemList.get(i);//图例名称
    legendEntity.textSize = 12;//图例文本字体大小
    legendEntity.textColor = Color.BLACK;//图例字体颜色
    legendEntity.color = listColor.get(i);//图例颜色,listColor是颜色集合
    legendEntities.add(legendEntity);
}
pieView.initData(legendEntities);//设置数据

最后返回的这个pieView就是包含自定义图例列表和饼图的View对象,直接在布局中使用就可以了

还有一个适配器类和一个实体类,如下:

//适配器
public class LegendViewAdapter extends BaseRecyclerAdapter {
    @Override
    public int getItemLayoutId(int viewType) {
        return R.layout.piechart_legend_recycler_item;//这个布局文件很简单,就是两个TextView并排显示,就不贴了
    }
    @Override
    public void setUpData(CommonHolder holder, int position, int viewType, LegendEntity data) {
        TextView tvColor = getView(holder, R.id.tv_color);
        TextView tvName = getView(holder, R.id.tv_name);
        tvName.setTextColor(data.textColor);
        tvName.setTextSize(data.textSize);
        tvColor.setBackgroundColor(data.color);
        tvName.setText(data.legend);
    }
}
//实体类
public class LegendEntity {
    public String legend;//图例文本
    public int color;//图例颜色
    public int textColor;//图例字体颜色
    public float textSize;//图例字体大小
}

另外我把MPChart这个库二次封装了一下,里面的饼图、雷达图都支持大量的图例显示,有需要的童鞋可以去我的github上瞅一瞅:https://github.com/fjm19960930/ZChart

注:适配器的那个父类是从一个私人库里面搞的,用起来很方便,需要导一下:

implementation 'com.github.zcolin:ZFrame:2.0.9'
implementation 'com.github.zcolin:ZRecyclerView:2.1.5'

你可能感兴趣的:(关于MPChart图例过多而无法全部显示的问题)