绘制统计表,势必要用到自定义控件,一个统计表,看起来单元项很多,但实际上做起来并不复杂。
要传递数据进来,用集合类最好。
要确定每个表格单元的宽和高,并根据数据数目和表格每列的高来决定自定义控件的高。
绘制表格线和表格单元背景的颜色,同时,绘制每个表格单元的文本。
自定义一个控件:
/** * Created by Administrator on 2015/10/20. */
public class ChartTableView extends View {
private int width;//控件宽
private int height;//控件高
private int dataNum;//数据量
private Paint mPaintText;//用于绘制文本
private Paint mPaintWhiteBg;//用于绘制白色背景
private Paint mPaintGreyBg;//用于绘制灰色背景
private Paint mPaintLightGrey;//用于绘制浅灰色背景
private Paint mPaintLine;//用于画表格的列线
private int visitSum;//总访问量
private int workerSum;//员工总数目
private float visitAverage;//平均访问量
private int textSize = SizeConvert.dip2px(getContext(), 13);//文本尺寸,dp转px
private ArrayList<VisitSummaryData> dataList;//总数据
public ChartTableView(Context context) {
super(context);
}
public ChartTableView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintLine = new Paint();
mPaintLine.setColor(Color.LTGRAY);
mPaintLine.setStrokeWidth(1);
mPaintLine.setAntiAlias(true);
mPaintText = new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setTextSize(textSize);
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setAntiAlias(true);
mPaintWhiteBg = new Paint();
mPaintWhiteBg.setColor(Color.WHITE);
mPaintWhiteBg.setStyle(Paint.Style.FILL);
mPaintWhiteBg.setAntiAlias(true);
mPaintGreyBg = new Paint();
mPaintGreyBg.setColor(Color.argb(255, 240, 240, 240));
mPaintGreyBg.setStyle(Paint.Style.FILL);
mPaintGreyBg.setAntiAlias(true);
mPaintLightGrey = new Paint();
mPaintLightGrey.setColor(Color.argb(255, 250, 250, 250));
mPaintLightGrey.setStyle(Paint.Style.FILL);
mPaintLightGrey.setAntiAlias(true);
dataList = new ArrayList<>();
}
/** * 得到dataList并确定一部分变量的值 * @param dataList */
public void setDataList(ArrayList<VisitSummaryData> dataList) {
this.dataList = dataList;
dataNum = dataList.size();
for(VisitSummaryData data:dataList){
visitSum += data.getVisitTotal();
workerSum += data.getWorkerTotal();
visitAverage += data.getVisitDaily();
}
visitAverage /= dataNum;
visitAverage = (float)(Math.round(visitAverage*10))/10;//让平均访问量只保留一位小数
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
//根据数据数量来得到控件高
if (dataNum != 0) {
height = (dataNum+1)*tableItemHeight;
}
//表格单元宽
tableItemWidth = width/4;
setMeasuredDimension(width, height);
}
private int tableItemWidth;
private int tableItemHeight = SizeConvert.dip2px(getContext(),36);//表格单元高
/** * 表格左上角的横纵坐标 */
private float startX;
private float startY;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制统计表表第一列
canvas.drawRect(startX, startY, startX + tableItemWidth, startY + tableItemHeight, mPaintLightGrey);
canvas.drawRect(startX + tableItemWidth, startY, width, startY + tableItemHeight, mPaintGreyBg);
canvas.drawText("合计(" + dataNum + ")", startX + tableItemWidth / 2, startY + tableItemHeight / 2+textSize/2, mPaintText);
canvas.drawText(visitSum+"",startX+tableItemWidth*3/2,startY+tableItemHeight/2+textSize/2,mPaintText);
canvas.drawText(workerSum+"",startX+tableItemWidth*5/2,startY+tableItemHeight/2+textSize/2,mPaintText);
canvas.drawText(visitAverage+"",startX+tableItemWidth*7/2,startY+tableItemHeight/2+textSize/2,mPaintText);
for(int i=0;i<dataNum;i++){
startY += tableItemHeight;
canvas.drawRect(startX, startY, startX + tableItemWidth, startY + tableItemHeight, mPaintLightGrey);
if(i%2==1) {
canvas.drawRect(startX + tableItemWidth, startY, width, startY + tableItemHeight, mPaintGreyBg);
}else {
canvas.drawRect(startX + tableItemWidth, startY, width, startY + tableItemHeight, mPaintWhiteBg);
}
canvas.drawText(dataList.get(i).getName(), startX + tableItemWidth / 2, startY + tableItemHeight / 2+textSize/2, mPaintText);
canvas.drawText(dataList.get(i).getVisitTotal()+"",startX+tableItemWidth*3/2,startY+tableItemHeight/2+textSize/2,mPaintText);
canvas.drawText(dataList.get(i).getWorkerTotal()+"",startX+tableItemWidth*5/2,startY+tableItemHeight/2+textSize/2,mPaintText);
canvas.drawText(dataList.get(i).getVisitDaily()+"",startX+tableItemWidth*7/2,startY+tableItemHeight/2+textSize/2,mPaintText);
canvas.drawLine(0, tableItemHeight * (i + 1), width, tableItemHeight * (i + 1), mPaintLine);
}
startX=0;
startY=0;
}
尺寸转换工具类:
public class SizeConvert {
/** * 将dp转换为sp */
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
/** * sp转dp */
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}
}
数据类,包含列表列单元的数据:
public class VisitSummaryData {
private int id;
private String name;
private int visitTotal;
private int workerTotal;
private float visitDaily;
public VisitSummaryData(int id, String name, int visitTotal, int workerTotal, float visitDaily) {
this.id = id;
this.name = name;
this.visitTotal = visitTotal;
this.workerTotal = workerTotal;
this.visitDaily = visitDaily;
}
public VisitSummaryData(String name, int visitTotal, int workerTotal, float visitDaily) {
this.name = name;
this.visitTotal = visitTotal;
this.workerTotal = workerTotal;
this.visitDaily = visitDaily;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getVisitTotal() {
return visitTotal;
}
public void setVisitTotal(int visitTotal) {
this.visitTotal = visitTotal;
}
public int getWorkerTotal() {
return workerTotal;
}
public void setWorkerTotal(int workerTotal) {
this.workerTotal = workerTotal;
}
public float getVisitDaily() {
return visitDaily;
}
public void setVisitDaily(int visitDaily) {
this.visitDaily = visitDaily;
}
}
主活动:
public class VisitSumTableActivity extends Activity {
private ChartTableView chartTableView;
private ArrayList<VisitSummaryData> dataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_visit_summary);
chartTableView = (ChartTableView) findViewById(R.id.chartTableView_visitSummary);
initChartTable();
}
private void initChartTable() {
dataList = new ArrayList<>();
dataList.add(new VisitSummaryData("涛涛",23,35,3.5f));
dataList.add(new VisitSummaryData("萌萌",22,42,2.5f));
dataList.add(new VisitSummaryData("秀秀",14,24,5.5f));
dataList.add(new VisitSummaryData("光光",66,347,3.0f));
dataList.add(new VisitSummaryData("瑞瑞",42,34,3.9f));
dataList.add(new VisitSummaryData("美美",24,44,0.5f));
dataList.add(new VisitSummaryData("笑笑",24,77,2.3f));
dataList.add(new VisitSummaryData("狒狒",87,69,9.8f));
dataList.add(new VisitSummaryData("飞飞",97,45,3.2f));
dataList.add(new VisitSummaryData("肥肥",69,38,4.5f));
dataList.add(new VisitSummaryData("小明",28,68,7.5f));
dataList.add(new VisitSummaryData("小红",27,34,9.5f));
//将数据传入自定义控件里
chartTableView.setDataList(dataList);
}
}
布局文件layout_visit_summary.xml:这个布局文件并不是原布局文件,我删除了一些东西,可以根据自己的需要,自定义布局文件,只要声明了自定义控件并能显示在恰当位置就行了。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<RelativeLayout android:id="@+id/relativeLayout_top" android:layout_width="match_parent" android:layout_height="60dp">
<LinearLayout android:id="@+id/linearlayout_backChart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:gravity="center" android:orientation="horizontal">
<Button android:layout_width="25dp" android:layout_height="25dp"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="报表"/>
</LinearLayout>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="拜访汇总" android:textSize="20dp"/>
<TextView android:id="@+id/textView_ranking" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:text="排名" android:textSize="16dp"/>
</RelativeLayout>
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="昨日,快消体验版"/>
<LinearLayout android:layout_width="match_parent" android:layout_height="45dp" android:background="#818297">
<TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="12dp" android:text="部门/人员"/>
<TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="12dp" android:gravity="center" android:text="拜访总数"/>
<TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="12dp" android:text="总工作人数"/>
<TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="12dp" android:text="日人均拜访"/>
</LinearLayout>
<ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:scrollbars="none">
<com.test.shiweiwei.myproject.widget.ChartTableView android:id="@+id/chartTableView_visitSummary" android:layout_width="match_parent" android:layout_height="wrap_content"/>
</ScrollView>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp" android:gravity="center">
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingRight="10dp">
<ImageButton android:id="@+id/button_visitSum_refresh" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button_visitSum_refresh" android:padding="5dp" android:textSize="10dp" android:text="刷新"/>
</RelativeLayout>
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="20dp">
<ImageButton android:id="@+id/button_visitSum_sift" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button_visitSum_sift" android:padding="5dp" android:textSize="10dp" android:text="筛选"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
程序员也需要有自己的乐趣,于是乎,我开通了音乐人账号,以后的作品将会上传到我的音乐人小站上。如果这篇博客帮助到您并且您也有时间,希望您能多关注,支持和推广,鼓励我将创作进行下去,先谢谢!