简单的一个比例分布条
2019-06-25 本文已影响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);
}
}