本文出自:http://blog.csdn.net/dt235201314/article/details/77248347

一丶效果演示


二丶需求分析技术点

1.产品要求,显示每个品类的占比,形成对比

2.MPAndroidChart可行性分析,可行,运用横向柱状图,设置最大值为100%,坐等设计图

3.MPAndroidChart实战问题分析

1).当品类多平分100%时,柱状图太少不好看,处理方式,最大值为百分比最大值,问题解决

2 ).品类名称长短不一时,对齐方式,无法解决,不得不弃疗

4.自定义分析,组合图,每行为单位,一个统一xml布局,最大值占满一行,动画

5.技术点分析

LinearLayout.LayoutParams完成宽度测量

ObjectAnimator完成动画效果

基础链接推荐:http://blog.csdn.net/harvic880925/article/details/50598322

ViewTreeObserver.OnPreDrawListener()测量绘制宽高

基础链接推荐:http://www.jianshu.com/p/5b026ffc36f1

ViewTreeObserver祥解:http://blog.csdn.net/hardworkingant/article/details/77408329


三丶核心代码

1.造数据,实体类

/** * 
 *     author : JinBiao *     CSDN : http://my.csdn.net/DT235201314 *     time   : 2017/08/16 *     desc   : 用于横向柱状图数据 *     version: 1.0 * 
*/public class BarDataEntity implements Serializable{ private List typeList; public List getTypeList() { return typeList; } public static class Type implements Serializable { private String typeName;//类型名称 private int sale;//销量 private double typeScale;//类型占比 public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public int getSale() { return sale; } public void setSale(int sale) { this.sale = sale; } public double getTypeScale() { return typeScale; } public void setTypeScale(double typeScale) { this.typeScale = typeScale; } } public List parseData(){ typeList = new ArrayList<>(); Random r = new Random(); int all=0; for (int i= 0;i<=6;i++){ Type type = new Type(); type.setSale(r.nextInt(100)); type.setTypeName("品类" + i); typeList.add(type); } for (int i= 0;i<=6;i++){ all+= typeList.get(i).getSale(); } for (int i= 0;i<=6;i++){ double typeScale = (double) typeList.get(i).getSale()/all; typeList.get(i).setTypeScale(typeScale); System.out.println("==>"+typeList.get(i).getTypeScale()); } return typeList; }}
2.行布局xml,参考设计图

<?xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="center_vertical"    android:orientation="horizontal"    android:paddingBottom="8dp"    android:paddingLeft="12dp"    android:paddingRight="10dp"    android:paddingTop="8dp">            android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:orientation="horizontal"        android:paddingRight="10dp">                    android:id="@+id/index"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="0" />                    android:id="@+id/name"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="right"            android:text="产品质量" />                android:id="@+id/bar_container"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="3"        android:orientation="horizontal"        android:gravity="left|center_vertical">                    android:id="@+id/bar"            android:layout_width="wrap_content"            android:layout_height="20dp"            android:background="#0CD3F4"            />                    android:id="@+id/percent"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:paddingLeft="10dp"            android:text="0%"            android:textColor="#0CD3F4" />    
3.核心方法

赋值 动画 测量

public void bindData() {    container = (LinearLayout) itemView.findViewById(R.id.container);    container.removeAllViews();    BarDataEntity data = new BarDataEntity();    data.parseData();    if (data == null || data.getTypeList() == null) {        return;    }    int color = Color.parseColor("#3FA0FF");    double maxScale = 0;    for (int i = 0; i < data.getTypeList().size(); i++) {        if (data.getTypeList().get(i).getTypeScale() > maxScale)            maxScale = data.getTypeList().get(i).getTypeScale();    }    for (int i = 0; i < data.getTypeList().size(); i++) {        final View item = LayoutInflater.from(itemView.getContext()).inflate(R.layout.h_bar_item, container, false);        final BarDataEntity.Type type = data.getTypeList().get(i);        ((TextView) item.findViewById(R.id.index)).setText("");        ((TextView) item.findViewById(R.id.name)).setText(type.getTypeName());        ((TextView) item.findViewById(R.id.index)).setText("" + i);        final View bar = item.findViewById(R.id.bar);        bar.setBackgroundColor(color);        ((TextView) item.findViewById(R.id.percent)).setText(format.format(type.getTypeScale() * 100) + "%");        ((TextView) item.findViewById(R.id.percent)).setTextColor(color);        final double finalMaxScale = maxScale;        item.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {            @Override            public boolean onPreDraw() {                item.getViewTreeObserver().removeOnPreDrawListener(this);                int barContainerWidth = item.findViewById(R.id.bar_container).getWidth();                int percentTxtWidth = item.findViewById(R.id.percent).getWidth();                final int initWidth = barContainerWidth - percentTxtWidth;                final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bar.getLayoutParams();                lp.width = (int) (initWidth * type.getTypeScale()/ finalMaxScale * 100 / 100);                bar.setLayoutParams(lp);                item.postDelayed(new Runnable() {                    @Override                    public void run() {                        final int initWidth = bar.getWidth();                        final ObjectAnimator anim = ObjectAnimator.ofFloat(bar, "alpha", 0.0F, 1.0F).setDuration(1500);                        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                            @Override                            public void onAnimationUpdate(ValueAnimator valueAnimator) {                                float cVal = (Float) anim.getAnimatedValue();                                lp.width = (int) (initWidth * cVal);                                bar.setLayoutParams(lp);                            }                        });                        anim.start();                    }                }, 0);                return false;            }        });        container.addView(item);    }}
四丶总结

1.MPAndroidChart虽然强大并不能解决所有问题,自定义才是王道

2.关于Java代码实现xml布局添加要多加学习,动画,简单实用的动画必须掌握。

3.关于View还有很多陌生的方法没有学习接触到,在自定义系列中逐渐掌握学习

五丶往期相关文章推荐

MPAndroidChart常见设置属性(一)——应用层 
MPAndroidChart项目实战(一)——实现对比性柱状图 
MPAndroidChart项目实战(二)——双平滑曲线(双折线图)和MarkView实现 
MPAndroidChart项目实战(三)——饼状图实现和文字重合问题解决 
MPAndroidChart项目实战(四)——柱状图实现及X轴文字不显示问题和柱状图上显示文字 
MPAndroidChart X轴文字斜着显示 
MPAndroidChart项目实战(五)——组合图实现趋势图 
MPAndroidChart项目实战(六)——自定义1MPAndroidChart滑动冲突解决(搞不定产品设计师就只能搞自己) 
MPAndroidChart项目实战(七)——自定义横向柱状图 
MPAndroidChart项目实战(八)——自定义分段堆积柱状图 
MPAndroidChart项目实战(九)——自定义带文字分段堆积柱状图  

六丶跪求关注下载源码,200粉小目标

欢迎关注我的博客及微信公众号,后面会给大家带来更多相关MPAndroidChart无法解决的仿MPAndroidChart图标自定义控件

源码下载记得顺便Star哦~

下载链接:https://github.com/JinBoy23520/MPAndroidChartDemoByJin



更多相关文章

  1. [转]Android的Camera架构介绍[有图]
  2. 10个android开源项目
  3. Android(安卓)中屏幕点击事件的实现
  4. Android使用Thread+Handler实现非UI线程更新界面
  5. Android(安卓)- 开发者应该深入学习的10个开源应用项目
  6. Android学习过程
  7. Android(安卓)studio删除工程项目
  8. Android学习笔记之——Android(安卓)Studio的安装(3.6版本)、Java
  9. android 图形底层实现

随机推荐

  1. android 中使文本(TextView 、button等可
  2. Android:adb常用命令汇总
  3. Android:控件GridView的使用
  4. android布局属性详解
  5. android 自定义SeekBar
  6. Android消息机制不完全解析(上)
  7. )Android之getSystemService
  8. Android(安卓)各种基础控件布局
  9. Android(安卓)Studio(五):修改Android(安
  10. android中java与js通信(可以用html来做页