美文网首页
简单的一个比例分布条

简单的一个比例分布条

作者: 榕城歌者 | 来源:发表于2019-06-25 12:21 被阅读0次

    做一个统计分布条,比如每个月的支出分布情况,某一类盈利的收入类型。
    这里没有采用柱状图、饼图的做法,所以想要柱状图或者饼图的可以不用往下看了,推荐一个图表框架MPAndroidChart
    ,可以实现柱状图、饼图等图表。

    效果图

    20190625120649.png

    实现原理

    原理很简单,就是继承一个LinearLayout,通过addView的方式动态去添加View,每一个支出类型就是一个TextView。采用动态添加的原因是,因为每个占比大小是不一样的,我们需要去计算出并且设置TextView的宽度。
    CoinPosition 封装的一个比例分布类,是该控件的一个静态内部类。

    public static class CoinPosition{
            //每个Item的占比以及名字
            private String coinName;
            private double percent;
    
            public CoinPosition(String coinName, double percent) {
                this.coinName = coinName;
                this.percent = percent;
            }
    
            public String getCoinName() {
                return coinName;
            }
    
            public void setCoinName(String coinName) {
                this.coinName = coinName;
            }
    
            public double getPercent() {
                return percent;
            }
    
            public void setPercent(double percent) {
                this.percent = percent;
            }
        }
    

    核心代码:

     private View getChildView(CoinPosition coinPosition,int index){
            LinearLayout.LayoutParams params;
            if(index == data.size()-1){//1
                params= new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);//2
            }else {
                params= new LinearLayout.LayoutParams((int) (parentWidth * coinPosition.percent),LayoutParams.MATCH_PARENT);//3
            }
            TextView textView=new TextView(getContext());
            textView.setLayoutParams(params);
            textView.setText(coinPosition.coinName);
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(12);
            textView.setTextColor(Color.parseColor("#FFFFFF"));
            if(index<colorRes.length){
                textView.setBackgroundColor(colorRes[index]);
            }
            return textView;
        }
    

    getChildView去获得子View的实例,并且将相应的名字、控件宽度已经背景颜色配置上去。
    注释1中判断索引位置,注释3在设定子View宽度的时候是有丢失精度取整的,所以在注释1中需要判断当前索引是否为数据的最后一个,最后一个不用注释3的方法得到宽度,否则的话会出现控件会出现空白,直接传入LayoutParams.MATCH_PARENT,利用完剩余的父布局宽度。

    完整的代码:

    package com.beidd.digiccy.myapplication;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.os.Handler;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author Hugh.HYS
     * @date 2019/6/24
     */
    public class DistributionLine extends LinearLayout {
    
        private List<CoinPosition> data=new ArrayList<>();
        private LayoutInflater layoutInflater;
        private int parentWidth;
        private int[] colorRes=new int[6];
    
        private Handler handler;
    
        public List<CoinPosition> getData() {
            return data;
        }
    
        public void setData(List<CoinPosition> data) {
    
            if(data.size()==0){
                return;
            }
            this.data.clear();
            this.data.addAll(data);
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    updateView();
                }
            },500);
    
        }
    
        public DistributionLine(Context context) {
            super(context);
            initConfig();
        }
    
        public DistributionLine(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initConfig();
        }
    
        public DistributionLine(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initConfig();
        }
    
        public DistributionLine(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            initConfig();
        }
    
        private void initConfig(){
            setOrientation(LinearLayout.HORIZONTAL);
            if(handler==null){
                handler=new Handler();
            }
            if(layoutInflater==null){
                layoutInflater= LayoutInflater.from(getContext());
            }
            //初始化颜色配置
            colorRes[0]= Color.parseColor("#DC143C");
            colorRes[1]= Color.parseColor("#4B0082");
            colorRes[2]= Color.parseColor("#FF0000");
            colorRes[3]= Color.parseColor("#00FFFF");
            colorRes[4]= Color.parseColor("#2E8B57");
            colorRes[5]= Color.parseColor("#DAA520");
        }
    
        private void updateView(){
            removeAllViews();
            parentWidth=getMeasuredWidth();
            for (int i=0;i<data.size();i++){
               addView(getChildView(data.get(i),i));
            }
    
        }
    
        private View getChildView(CoinPosition coinPosition,int index){
            LinearLayout.LayoutParams params;
            if(index == data.size()-1){
                params= new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
            }else {
                params= new LinearLayout.LayoutParams((int) (parentWidth * coinPosition.percent),LayoutParams.MATCH_PARENT);
            }
            TextView textView=new TextView(getContext());
            textView.setLayoutParams(params);
            textView.setText(coinPosition.coinName);
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(12);
            textView.setTextColor(Color.parseColor("#FFFFFF"));
            if(index<colorRes.length){
                textView.setBackgroundColor(colorRes[index]);
            }
            return textView;
        }
    
        public static class CoinPosition{
            //每个Item的占比以及名字
            private String coinName;
            private double percent;
    
            public CoinPosition(String coinName, double percent) {
                this.coinName = coinName;
                this.percent = percent;
            }
    
            public String getCoinName() {
                return coinName;
            }
    
            public void setCoinName(String coinName) {
                this.coinName = coinName;
            }
    
            public double getPercent() {
                return percent;
            }
    
            public void setPercent(double percent) {
                this.percent = percent;
            }
        }
    
    }
    
    

    测试:

    package com.beidd.digiccy.myapplication;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author Hugh.HYS
     * @date 2019/4/3
     */
    public class TestActivity extends AppCompatActivity {
    
        private DistributionLine distributionLine;
        final List<DistributionLine.CoinPosition> data=new ArrayList<>();
    
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.act);
            distributionLine=findViewById(R.id.dis);
            data.clear();
            data.add(new DistributionLine.CoinPosition("投资",0.3));
            data.add(new DistributionLine.CoinPosition("衣服",0.2));
            data.add(new DistributionLine.CoinPosition("吃喝",0.2));
            data.add(new DistributionLine.CoinPosition("玩乐",0.1));
            data.add(new DistributionLine.CoinPosition("出行",0.1));
            data.add(new DistributionLine.CoinPosition("其它",0.1));
            distributionLine.setData(data);
    
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:简单的一个比例分布条

          本文链接:https://www.haomeiwen.com/subject/vmrtcctx.html