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

一丶效果演示

MPAndroidChart项目实战(七)——自定义横向柱状图_第1张图片

二丶需求分析技术点

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项目中每个文件的作用
  2. Android studio导入Github的项目
  3. 进入android项目组的第一天
  4. Android消息通信之无所不能的第三方开源项目EventBus
  5. android 实战 AppCompat实现Action Bar
  6. Android 开发一定要看的15个实战项目
  7. Weex 04 Weex中Android项目的生成和交互
  8. Android项目应用程序—应用程序及生命周期

随机推荐

  1. android SystemServer.java启动的服务有
  2. Android(安卓)实现拍照功能
  3. android 用ant打包apk
  4. JAVA线程——选自《Learn Java for Andro
  5. Android_UI_全屏去掉标题栏和状态栏的两
  6. Android(安卓)自带的系统分享功能
  7. android TypedValue.applyDimension()的
  8. Android分享小程序并且互跳(小程序回到APP
  9. Android默认设置保存在哪里
  10. Android(安卓)利用发送Intent播放本地视