常常见很多应用设定的条形柱状分布图,具体到自己做的时候却不得而知,一开始想过用ProgressBar来实现,后来发现局限性很大,尝试搜索了一下,可能是自己搜索的条件有误,也没有得到一个合适的参考Demo。虽然看上去简单的几个色块,但是如果和数据相结合动态改变的话,也不至于每次都去画色块吧?偶然想到动态的添加数据,何不用RecyclerView或者listView来实现不同大小和分布位置不一的色块柱形图呢,如果你也需要这样的效果,那就搬个凳子坐下来,听我说道说道吧:
首先创建RecyclerView的过程,就不详细细说了,直接贴代码片段吧
XML布局文件
主界面中声明RecyclerView的横向布局设置,需要注意的两个地方,一个是创建的Test实体类,一个是对应的适配器,主要是实现效果就是放在这两类中的。
class Test {
private int Color_Type;//背景颜色类别
private int Color_length;//色块长度
public int getColor_Type() {
return Color_Type;
}
public void setColor_Type(int color_Type) {
Color_Type = color_Type;
}
public int getColor_length() {
return Color_length;
}
public void setColor_length(int color_length) {
Color_length = color_length;
}
}
适配器类:
class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestHolder> {
private Context mContext;
private List<Test> Test_list;
private int Total_Number = 0;
/**
* 适配器
*
* @param mContext 上下文对象
* @param Test_list 每个色块对应属性值
* @param Total_Number 总色块数
*/
public TestAdapter(Context mContext, ArrayList<Test> Test_list, int Total_Number) {
this.mContext = mContext;
this.Test_list = Test_list;
this.Total_Number = Total_Number;
}
@Override
public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.test_item, parent, false);
TestHolder holder = new TestHolder(view);
return holder;
}
@Override
public void onBindViewHolder(TestHolder holder, int position) {
if (Test_list.get(position).getColor_Type() == 0) {
//第一种色块
holder.Test_item_view.setBackgroundColor(mContext.getColor(R.color.Test_red));
} else if (Test_list.get(position).getColor_Type() == 1) {
//第二种色块
holder.Test_item_view.setBackgroundColor(mContext.getColor(R.color.Test_yellow));
} else if (Test_list.get(position).getColor_Type() == 2) {
//第三种色块
holder.Test_item_view.setBackgroundColor(mContext.getColor(R.color.Test_color));
}
//设置每个格子高度
setLinearLayout(holder.Test_item_ll, ScreenUtils.getScreenWidth(mContext) * Test_list.get(position).getColor_length() / Total_Number);
}
/**
* * 设置每个色块宽度
*
* @param mLinearLayout 对应需要设置LinearLayout
* @param Test_width 对应的宽度
*/
private void setLinearLayout(LinearLayout mLinearLayout, int Test_width) {
ViewGroup.LayoutParams lp;
lp = mLinearLayout.getLayoutParams();
lp.width = Test_width;
lp.height = 200;
mLinearLayout.setLayoutParams(lp);
}
@Override
public int getItemCount() {
return Test_list.size();
}
public class TestHolder extends RecyclerView.ViewHolder {
private View Test_item_view;
private LinearLayout Test_item_ll;
@RequiresApi(api = Build.VERSION_CODES.M)
public TestHolder(View itemView) {
super(itemView);
Test_item_view = itemView.findViewById(R.id.test_item_view);
Test_item_ll = itemView.findViewById(R.id.test_item_ll);
}
}
}
这里主要说明几个关键点:
1、关于setLinearLayout设置宽度,通过设置item(也就是每个色块)对应父布局LinearLayout布局的宽度,来实现每个色块的宽度大小、所占比例。
这里还可以提供一种方法
mLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(400, 200));
不过此类方法容易报错:
01-03 01:48:12.914: E/AndroidRuntime(3353): FATAL EXCEPTION: main
01-03 01:48:12.914: E/AndroidRuntime(3353): java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams
建议使用Demo中的方案
2、ScreenUtils的说明,此类是比较常见的工具类,用来计算屏幕宽度的,我的构想是知道横向柱形图总共的色块数量,通过比例将横向屏幕的宽度分割成等比例的份数,在填充上对应的颜色值,所以这里需要根据手机屏幕宽度值来计算对应的色块
具体这个工具类可以参考该链接:https://blog.youkuaiyun.com/firelightdragon/article/details/53068977
3、ScreenUtils.getScreenWidth(mContext) * Test_list.get(position).getColor_length() / Total_Number
计算说明:ScreenUtils.getScreenWidth(mContext)——获取屏幕宽度
est_list.get(position).getColor_length()——每个色块对应的宽度占比
Total_Number——色块总数
这里讲一下使用方法:
TestAdapter = new TestAdapter(this, test_list, 10);
将色块的总数、对应的每个色块的占比传入即可,可以随便改变色块的数量、占比值、颜色,而且不会超过屏幕的总宽度,根据数据随机改变,更加随意调配。