自定义的表格view

表格的实现有很多种,有自定义的,有利用listview或者recyclerview的item中控件四周加线的。用listview、recyclerview实现的,有复用机制,可能更优化,但是可能对每一个表格,你需要去写一个item和对应的adapter。反正每一种实现都有自己的实用性,根据自己的需求用比较合适的方式就好。


下面开始介绍这个自定义的这个表格view

首先,这个东西是在现有轮子上根据自己项目需求修修改改后实现的,所以感谢原作者,github地址:https://github.com/KungFuBrother/TableView

看看效果图

实现介绍

1.自定义属性

  /**
     * 单元格基准宽度,设权重的情况下,为最小单元格宽度
     */
    private float unitColumnWidth;     //最小单元格宽度
    private float dividerWidth;        //分割线宽度
    private int dividerColor;          //分割线颜色
    private float textSize;            //表格内容字体大小
    private int textColor;             //表格内容字体颜色
    private int headerColor;           //表格标题背景颜色
    private float headerTextSize;      //表格标题字体大小
    private int headerTextColor;       //表格标题字体颜色
    private int oneColor;              //一种表格内容背景颜色
    private int twoColor;              //一种表格内容背景颜色
    private int tbDistance;           //表格内容字体上下侧与线的距离
    private int lrDistance;           //表格内容字体左右侧与线的距离

    private int rowCount;             //行数总和(含标题)
    private int columnCount;          //列数总和

    private TextPaint paint;          //画表格内容字体的画笔
    private TextPaint headPaint;      //画表格标题的字体的画笔

    private float[] columnLefts;     //每列左侧坐标集合
    private float[] columnWidths;    //每列宽度的集合
    private float[] lineHeight;      //行高度的集合(只是每行字体的高度集合)
    private float[] completeRowHeight;   //每行完整高度的集合(包含文字,间隔等参数)
    private String[] headers;        //标题的数组
    private float headerHeight;      //标题的高度

    private float[] columnWeights;     //每列的权重
    private List<String[]> tableContents;    //表格的内容数据源
    private HashMap<Integer,Layout.Alignment> aline ;    //某列的字体的Aline方式,默认每列的均居中显示

2.关键方法

---initTableSize()

该方法是在初始化自定义属性时调用,初始化表格的列数

/**
     * 初始化行列数
     */
    private void initTableSize() {
        rowCount = tableContents.size();
        if (rowCount > 0) {
            //如果设置了表头,根据表头数量确定列数
            columnCount = tableContents.get(0).length;
        }
    }

---onMeasure()

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //通过权重计算最小单元格宽度

        int weightSum = 0;
        if (columnWeights != null) {
            for (int i = 0; i < columnCount; i++) {
                if (columnWeights.length > i) {
                    weightSum += columnWeights[i];
                } else {
                    weightSum += 1;
                }
            }
        } else {
            //默认等分,每列权重为1
            weightSum = columnCount;
        }

        if(weightSum==0){
            setMeasuredDimension(0,0);
            return;
        }

        //计算宽度及列宽
        float width;
        if (unitColumnWidth == 0) {
            //未设置宽度,根据控件宽度来确定最小单元格宽度
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            width = getMeasuredWidth();
            unitColumnWidth = (width - (columnCount + 1) * dividerWidth) / weightSum;

        } else {
            //设置了最小单元格宽度
            width = dividerWidth * (columnCount + 1) + unitColumnWidth * weightSum;
        }

        //计算本view的高度
        calculateColumns();
        float height = 0.0f;
        headerHeight=getLineHeight(headers,headPaint);
        height+=dividerWidth*2+headerHeight+tbDistance*2;
        if(tableContents.size()>1){
            for(int i=0;i<tableContents.size()-1;i++){
                lineHeight[i]=getLineHeight(tableContents.get(i+1),paint);
                height+=lineHeight[i];
            }
            height+=dividerWidth*(tableContents.size()-1)+(tableContents.size()-1)*(tbDistance*2);
        }
        setMeasuredDimension((int) width, (int) height);
    }

其中calculateColumns():

 /**
     * 计算每列左端坐标及列宽
     */
    private void calculateColumns() {
        columnLefts = new float[columnCount];
        columnWidths = new float[columnCount];
        lineHeight=new float[tableContents.size()];
        for (int i = 0; i < columnCount; i++) {
            columnLefts[i] = getColumnLeft(i);
            columnWidths[i] = getColumnWidth(i);
        }
    }

    private float getColumnLeft(int columnIndex) {
        if (columnWeights == null) {
            return columnIndex * (unitColumnWidth + dividerWidth);
        }
        //计算左边的权重和
        int weightSum = 0;
        for (int i = 0; i < columnIndex; i++) {
            if (columnWeights.length > i) {
                weightSum += columnWeights[i];
            } else {
                weightSum += 1;
            }
        }
        return columnIndex * dividerWidth + weightSum * unitColumnWidth;
    }

    private float getColumnWidth(int columnIndex) {
        if (columnWeights == null) {
            return unitColumnWidth;
        }
        float weight = columnWeights.length > columnIndex ? columnWeights[columnIndex] : 1;
        return weight * unitColumnWidth;
    }

getLineHeight():获取每行的高度

 /**
     * 获取每行数据的高度
     * @param strings
     * @return
     */
    private float getLineHeight(String[] strings,TextPaint paint) {
        float height=0.0f;
        for(int i=0;i<strings.length;i++){
            StaticLayout layout = new StaticLayout(strings[i]==null?" ":strings[i], paint, (int)(columnWidths[i]-Util.dip2px(getContext(),5)*2), Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
            int height1 = layout.getHeight();
            if(i==0){
                height=height1;
            }
            if(i>0&&height1>height){
                height=height1;
            }
        }
        return height;
    }

---onDraw():

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画表格背景,现在为颜色
        drawHeader(canvas);
        //画表格的线
        drawFramework(canvas);
        //画表格文字内容
        drawContent(canvas);
    }
 /**
     * 画背景色
     *
     * @param canvas
     */
    private void drawHeader(Canvas canvas) {
        //画标题背景色
        //这里是用path画上侧是圆角的矩形
        paint.setColor(headerColor);
        RectF rectF = new RectF(dividerWidth, dividerWidth, getWidth() - dividerWidth, headerHeight + dividerWidth+tbDistance*2);
        Path path = new Path();
        path.addRoundRect(rectF,new float[]{8, 8, 8, 8, 0, 0, 0, 0}, Path.Direction.CCW);
        canvas.drawPath(path, paint);
        //画内容背景色
        float vh = dividerWidth+tbDistance*2+headerHeight+dividerWidth;
        for(int i=0;i<rowCount;i++){
            if(i%2==0){
                paint.setColor(oneColor);
            }
            else{
                paint.setColor(twoColor);
            }
            if(i!=rowCount-1){
                canvas.drawRect(dividerWidth,vh,getWidth()-dividerWidth,vh+lineHeight[i]+2*tbDistance,paint);
            }
            else{
                RectF rectF1 = new RectF(dividerWidth,vh,getWidth()-dividerWidth,vh+lineHeight[i]+2*tbDistance);
                Path path1 = new Path();
                path.addRoundRect(rectF1,new float[]{0, 0, 0, 0,8, 8, 8, 8}, Path.Direction.CCW);
                canvas.drawPath(path1, paint);
            }
            vh+=dividerWidth+2*tbDistance+lineHeight[i];
        }

    }
/**
     * 画整体表格框架
     */
    private void drawFramework(Canvas canvas) {
        paint.setColor(dividerColor);   
        float viewH=0.0f;

        //画每一行的横线
        for (int i = 0; i < rowCount+1 ; i++) {
            if(i==0){
                viewH=dividerWidth;
                continue;
            }
            else if(i==1){
                viewH+=tbDistance*2+headerHeight+dividerWidth;
                continue;
            }
            if(i!=rowCount){
                canvas.drawRect(40,viewH+tbDistance*2+lineHeight[i-2],getWidth()-40,viewH+tbDistance*2+lineHeight[i-2]+dividerWidth,paint);
            }

            viewH+=tbDistance*2+lineHeight[i-2]+dividerWidth;
            paint.setColor(dividerColor);
        }
    }
 /**
     * 画内容
     */
    private void drawContent(Canvas canvas) {

        for (int i = 0; i < rowCount; i++) {
            final String[] rowContent = tableContents.size() > i ? tableContents.get(i) : new String[0];
            canvas.save();
            paint.setFakeBoldText(false);
            if (i == 0) {
                //设置表头文字画笔样式
                paint.setColor(headerTextColor);
                paint.setTextSize(headerTextSize);
                paint.setFakeBoldText(true);
                canvas.translate(dividerWidth+lrDistance,dividerWidth+tbDistance);
            }
            else{
                if(i==1){
                    canvas.translate(dividerWidth,headerHeight+tbDistance+dividerWidth+tbDistance);
                }
                else{
                    canvas.translate(dividerWidth,lineHeight[i-2]+tbDistance+dividerWidth+tbDistance);
                }
            }
            float tr=0.0f;
            for (int j = 0; j < columnCount; j++) {
                if (rowContent.length > j) {
                    StaticLayout sl;
                    if(i!=0){
                        sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                        if(sl.getLineCount()>1){
                            if(aline.containsKey(j)){
                                sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),aline.get(j), 1.0F, 0.0F, false);
                            }
                            else{
                                sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                            }
                        }
                        else{
                            sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                        }
                    }
                    else{
                        sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2), Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                    }
                    int slHeight = sl.getHeight();
                    if(i==0){
                        if(slHeight!=headerHeight){
                            canvas.save();
                            canvas.translate(0,headerHeight/2-slHeight/2);
                        }
                    }
                    else{
                        if(slHeight!=lineHeight[i-1]){
                            canvas.save();
                            canvas.translate(0,lineHeight[i-1]/2-slHeight/2);
                        }
                    }
                    sl.draw(canvas);
                    canvas.save();
                    if(i==0){
                        if(slHeight!=headerHeight){
                            canvas.translate(0,-1*(headerHeight/2-slHeight/2));
                        }
                    }
                    else{
                        if(slHeight!=lineHeight[i-1]){
                            canvas.translate(0,-1*(lineHeight[i-1]/2-slHeight/2));
                        }
                    }
                    try{
                        canvas.translate((columnWidths[j]+dividerWidth),0);
                        tr+=(columnWidths[j]+dividerWidth);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
            if (i == 0) {
                //恢复表格文字画笔样式
                paint.setColor(textColor);
                paint.setTextSize(textSize);
            }
            canvas.translate(-1*(tr+dividerWidth),0);
        }
    }

---清除数据

 /**
     * 清除表格内容
     */
    public CustomerTableView clearTableContents() {
        columnWeights = null;
        tableContents.clear();
        return this;
    }

---暴露的方法,用于外侧调用以绘制表格

 /**
     * 设置数据后刷新表格
     */
    public void refreshTable() {
        initTableSize();
        requestLayout();
    }

3.调用

 cTv.clearTableContents();   //设置数据前把表格内容清空
 cTv.setHeader(t_headvalues);//设置表格标题内容,是一个String[]
 cTv.setColumnWeights(weight_t);//设置每列权重
 cTv.addContents(getData(msgObj,t_headvalues)); //设置表格内容数据,是List<String[]>
 cTv.refreshTable();         //调用该方法,重绘表格刷新数据

4.自定义的属性

<declare-styleable name="CustomerTableView">
        <attr name="unitColWidth" format="dimension" />
        <attr name="headercolor" format="color" />
        <attr name="dividerwidth" format="dimension" />
        <attr name="dividercolor" format="color" />
        <attr name="textsize" format="dimension" />
        <attr name="textcolor" format="color" />
        <attr name="headertextSize" format="dimension" />
        <attr name="headertextColor" format="color" />
        <attr name="lrDistance" format="dimension"/>
        <attr name="tbDistance" format="dimension"/>
        <attr name="oneColor" format="color"/>
        <attr name="twoColor" format="color"/>
    </declare-styleable>

5.最后贴一下全部代码

public class CustomerTableView extends View {

    /**
     * 单元格基准宽度,设权重的情况下,为最小单元格宽度
     */
    private float unitColumnWidth;     //最小单元格宽度
    private float dividerWidth;        //分割线宽度
    private int dividerColor;          //分割线颜色
    private float textSize;            //表格内容字体大小
    private int textColor;             //表格内容字体颜色
    private int headerColor;           //表格标题背景颜色
    private float headerTextSize;      //表格标题字体大小
    private int headerTextColor;       //表格标题字体颜色
    private int oneColor;              //一种表格内容背景颜色
    private int twoColor;              //一种表格内容背景颜色
    private int tbDistance;           //表格内容字体上下侧与线的距离
    private int lrDistance;           //表格内容字体左右侧与线的距离

    private int rowCount;             //行数总和(含标题)
    private int columnCount;          //列数总和

    private TextPaint paint;          //画表格内容字体的画笔
    private TextPaint headPaint;      //画表格标题的字体的画笔

    private float[] columnLefts;     //每列左侧坐标集合
    private float[] columnWidths;    //每列宽度的集合
    private float[] lineHeight;      //行高度的集合(只是每行字体的高度集合)
    private float[] completeRowHeight;   //每行完整高度的集合(包含文字,间隔等参数)
    private String[] headers;        //标题的数组
    private float headerHeight;      //标题的高度

    private float[] columnWeights;     //每列的权重
    private List<String[]> tableContents;    //表格的内容数据源
    private HashMap<Integer,Layout.Alignment> aline ;    //某列的字体的Aline方式,默认每列的均居中显示

    public CustomerTableView(Context context) {
        super(context);
        init(null);
    }

    public CustomerTableView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        paint = new TextPaint();
        paint.setAntiAlias(true);
        headPaint=new TextPaint();
        headPaint.setAntiAlias(true);
        headPaint.setTextAlign(Paint.Align.CENTER);

        tableContents = new ArrayList<>();
        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomerTableView);
            unitColumnWidth = typedArray.getDimensionPixelSize(R.styleable.CustomerTableView_unitColWidth, 0);
            dividerWidth = typedArray.getDimensionPixelSize(R.styleable.CustomerTableView_dividerwidth, 1);
            dividerColor = typedArray.getColor(R.styleable.CustomerTableView_dividercolor, Color.parseColor("#E1E1E1"));
            textSize = typedArray.getDimensionPixelSize(R.styleable.CustomerTableView_textsize, Util.dip2px(getContext(), 10));
            textColor = typedArray.getColor(R.styleable.CustomerTableView_textcolor, Color.parseColor("#000000"));
            headerColor = typedArray.getColor(R.styleable.CustomerTableView_headercolor, Color.parseColor("#00ffffff"));
            headerTextSize = typedArray.getDimensionPixelSize(R.styleable.CustomerTableView_headertextSize, Util.dip2px(getContext(), 10));
            headerTextColor = typedArray.getColor(R.styleable.CustomerTableView_headertextColor, Color.parseColor("#999999"));
            tbDistance=typedArray.getDimensionPixelOffset(R.styleable.CustomerTableView_tbDistance,Util.dip2px(getContext(),5));
            lrDistance=typedArray.getDimensionPixelOffset(R.styleable.CustomerTableView_lrDistance,Util.dip2px(getContext(),5));
            oneColor=typedArray.getColor(R.styleable.CustomerTableView_oneColor, Color.parseColor("#ffffff"));
            twoColor=typedArray.getColor(R.styleable.CustomerTableView_twoColor, Color.parseColor("#ffffff"));
            typedArray.recycle();
        } else {
            unitColumnWidth = 0;
            dividerWidth = 1;
            dividerColor = Color.parseColor("#E1E1E1");
            textSize = Util.dip2px(getContext(), 10);
            textColor = Color.parseColor("#000000");
            headerColor = Color.parseColor("#00ffffff");
            headerTextSize = Util.dip2px(getContext(), 10);
            headerTextColor = Color.parseColor("#111111");
            tbDistance=Util.dip2px(getContext(),5);
            lrDistance=Util.dip2px(getContext(),5);
            oneColor=Color.parseColor("#ffffff");
            twoColor=Color.parseColor("#ffffff");
        }
        headPaint.setColor(headerColor);
        headPaint.setTextSize(headerTextSize);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        aline=new HashMap<>();
        initTableSize();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //通过权重计算最小单元格宽度

        int weightSum = 0;
        if (columnWeights != null) {
            for (int i = 0; i < columnCount; i++) {
                if (columnWeights.length > i) {
                    weightSum += columnWeights[i];
                } else {
                    weightSum += 1;
                }
            }
        } else {
            //默认等分,每列权重为1
            weightSum = columnCount;
        }

        if(weightSum==0){
            setMeasuredDimension(0,0);
            return;
        }

        //计算宽度及列宽
        float width;
        if (unitColumnWidth == 0) {
            //未设置宽度,根据控件宽度来确定最小单元格宽度
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            width = getMeasuredWidth();
            unitColumnWidth = (width - (columnCount + 1) * dividerWidth) / weightSum;

        } else {
            //设置了最小单元格宽度
            width = dividerWidth * (columnCount + 1) + unitColumnWidth * weightSum;
        }

        //计算本view的高度
        calculateColumns();
        float height = 0.0f;
        headerHeight=getLineHeight(headers,headPaint);
        height+=dividerWidth*2+headerHeight+tbDistance*2;
        if(tableContents.size()>1){
            for(int i=0;i<tableContents.size()-1;i++){
                lineHeight[i]=getLineHeight(tableContents.get(i+1),paint);
                height+=lineHeight[i];
            }
            height+=dividerWidth*(tableContents.size()-1)+(tableContents.size()-1)*(tbDistance*2);
        }
        setMeasuredDimension((int) width, (int) height);
    }

    /**
     * 获取每行数据的高度
     * @param strings
     * @return
     */
    private float getLineHeight(String[] strings,TextPaint paint) {
        float height=0.0f;
        for(int i=0;i<strings.length;i++){
            StaticLayout layout = new StaticLayout(strings[i]==null?" ":strings[i], paint, (int)(columnWidths[i]-Util.dip2px(getContext(),5)*2), Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
            int height1 = layout.getHeight();
            if(i==0){
                height=height1;
            }
            if(i>0&&height1>height){
                height=height1;
            }
        }
        return height;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画表格标题
        drawHeader(canvas);
        drawFramework(canvas);
        drawContent(canvas);
    }

    /**
     * 画背景色
     *
     * @param canvas
     */
    private void drawHeader(Canvas canvas) {
        //画头部背景色
        paint.setColor(headerColor);
//        canvas.drawRect(dividerWidth, dividerWidth, getWidth() - dividerWidth, headerHeight + dividerWidth+tbDistance*2, paint);
        RectF rectF = new RectF(dividerWidth, dividerWidth, getWidth() - dividerWidth, headerHeight + dividerWidth+tbDistance*2);
        Path path = new Path();
        path.addRoundRect(rectF,new float[]{8, 8, 8, 8, 0, 0, 0, 0}, Path.Direction.CCW);
        canvas.drawPath(path, paint);
        //画内容背景色
        float vh = dividerWidth+tbDistance*2+headerHeight+dividerWidth;
        for(int i=0;i<rowCount;i++){
            if(i%2==0){
                paint.setColor(oneColor);
            }
            else{
                paint.setColor(twoColor);
            }
            if(i!=rowCount-1){
                canvas.drawRect(dividerWidth,vh,getWidth()-dividerWidth,vh+lineHeight[i]+2*tbDistance,paint);
            }
            else{
                RectF rectF1 = new RectF(dividerWidth,vh,getWidth()-dividerWidth,vh+lineHeight[i]+2*tbDistance);
                Path path1 = new Path();
                path.addRoundRect(rectF1,new float[]{0, 0, 0, 0,8, 8, 8, 8}, Path.Direction.CCW);
                canvas.drawPath(path1, paint);
            }
            vh+=dividerWidth+2*tbDistance+lineHeight[i];
        }

    }

    /**
     * 画整体表格框架
     */
    private void drawFramework(Canvas canvas) {
        paint.setColor(dividerColor);
//        for (int i = 0; i < columnCount + 1; i++) {
//            if (i == 0) {
//                //最左侧分割线
//                canvas.drawRect(0, 0, dividerWidth, getHeight(), paint);
//                continue;
//            }
//            if (i == columnCount) {
//                //最右侧分割线
//                canvas.drawRect(getWidth() - dividerWidth, 0, getWidth(), getHeight(), paint);
//
//                continue;
//            }
//            canvas.drawRect(columnLefts[i], 0, columnLefts[i] + dividerWidth, getHeight(), paint);
//        }
        float viewH=0.0f;

        //画每一行的横线
        for (int i = 0; i < rowCount+1 ; i++) {
            if(i==0){
                viewH=dividerWidth;
//                canvas.drawRect(40, 0, getWidth(), dividerWidth-40, paint);
                continue;
            }
            else if(i==1){
                viewH+=tbDistance*2+headerHeight+dividerWidth;
//                canvas.drawRect(40, headerHeight+dividerWidth+tbDistance*2, getWidth()-40,  headerHeight+dividerWidth+tbDistance*2+dividerWidth, paint);
                continue;
            }
            if(i!=rowCount){
                canvas.drawRect(40,viewH+tbDistance*2+lineHeight[i-2],getWidth()-40,viewH+tbDistance*2+lineHeight[i-2]+dividerWidth,paint);
            }

            viewH+=tbDistance*2+lineHeight[i-2]+dividerWidth;
            paint.setColor(dividerColor);
        }
    }

    /**
     * 画内容
     */
    private void drawContent(Canvas canvas) {

        for (int i = 0; i < rowCount; i++) {
            final String[] rowContent = tableContents.size() > i ? tableContents.get(i) : new String[0];
            canvas.save();
            paint.setFakeBoldText(false);
            if (i == 0) {
                //设置表头文字画笔样式
                paint.setColor(headerTextColor);
                paint.setTextSize(headerTextSize);
                paint.setFakeBoldText(true);
                canvas.translate(dividerWidth+lrDistance,dividerWidth+tbDistance);
            }
            else{
                if(i==1){
                    canvas.translate(dividerWidth,headerHeight+tbDistance+dividerWidth+tbDistance);
                }
                else{
                    canvas.translate(dividerWidth,lineHeight[i-2]+tbDistance+dividerWidth+tbDistance);
                }
            }
            float tr=0.0f;
            for (int j = 0; j < columnCount; j++) {
                if (rowContent.length > j) {
                    StaticLayout sl;
                    if(i!=0){
                        sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                        if(sl.getLineCount()>1){
                            if(aline.containsKey(j)){
                                sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),aline.get(j), 1.0F, 0.0F, false);
                            }
                            else{
                                sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                            }
                        }
                        else{
                            sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2),Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                        }
                    }
                    else{
                        sl=new StaticLayout((rowContent[j]==null?" ":rowContent[j]),paint,(int)(columnWidths[j]-lrDistance*2), Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, false);
                    }
                    int slHeight = sl.getHeight();
                    if(i==0){
                        if(slHeight!=headerHeight){
                            canvas.save();
                            canvas.translate(0,headerHeight/2-slHeight/2);
                        }
                    }
                    else{
                        if(slHeight!=lineHeight[i-1]){
                            canvas.save();
                            canvas.translate(0,lineHeight[i-1]/2-slHeight/2);
                        }
                    }
                    sl.draw(canvas);
                    canvas.save();
                    if(i==0){
                        if(slHeight!=headerHeight){
                            canvas.translate(0,-1*(headerHeight/2-slHeight/2));
                        }
                    }
                    else{
                        if(slHeight!=lineHeight[i-1]){
                            canvas.translate(0,-1*(lineHeight[i-1]/2-slHeight/2));
                        }
                    }
                    try{
                        canvas.translate((columnWidths[j]+dividerWidth),0);
                        tr+=(columnWidths[j]+dividerWidth);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
            if (i == 0) {
                //恢复表格文字画笔样式
                paint.setColor(textColor);
                paint.setTextSize(textSize);
            }
            canvas.translate(-1*(tr+dividerWidth),0);
        }
    }

    /**
     * 计算每列左端坐标及列宽
     */
    private void calculateColumns() {
        columnLefts = new float[columnCount];
        columnWidths = new float[columnCount];
        lineHeight=new float[tableContents.size()];
        for (int i = 0; i < columnCount; i++) {
            columnLefts[i] = getColumnLeft(i);
            columnWidths[i] = getColumnWidth(i);
        }
    }

    private float getColumnLeft(int columnIndex) {
        if (columnWeights == null) {
            return columnIndex * (unitColumnWidth + dividerWidth);
        }
        //计算左边的权重和
        int weightSum = 0;
        for (int i = 0; i < columnIndex; i++) {
            if (columnWeights.length > i) {
                weightSum += columnWeights[i];
            } else {
                weightSum += 1;
            }
        }
        return columnIndex * dividerWidth + weightSum * unitColumnWidth;
    }

    private float getColumnWidth(int columnIndex) {
        if (columnWeights == null) {
            return unitColumnWidth;
        }
        float weight = columnWeights.length > columnIndex ? columnWeights[columnIndex] : 1;
        return weight * unitColumnWidth;
    }



    /**
     * 清除表格内容
     */
    public CustomerTableView clearTableContents() {
        columnWeights = null;
        tableContents.clear();
        return this;
    }

    /**
     * 设置每列的权重
     *
     * @param columnWeights
     * @return
     */
    public CustomerTableView setColumnWeights(float... columnWeights) {
        this.columnWeights = columnWeights;
        return this;
    }

    /**
     * 设置表头
     *
     * @param headers
     */
    public CustomerTableView setHeader(String... headers) {
        tableContents.add(0, headers);
        this.headers=headers;
        return this;
    }

    /**
     * 设置表格内容
     */
    public CustomerTableView addContent(String... contents) {
        tableContents.add(contents);
        return this;
    }

    /**
     * 设置表格内容
     */
    public CustomerTableView addContents(List<String[]> contents) {
        tableContents.addAll(contents);
        return this;
    }

    /**
     * 初始化行列数
     */
    private void initTableSize() {
        rowCount = tableContents.size();
        if (rowCount > 0) {
            //如果设置了表头,根据表头数量确定列数
            columnCount = tableContents.get(0).length;
        }
    }

    /**
     * 设置数据后刷新表格
     */
    public void refreshTable() {
        initTableSize();
        requestLayout();
    }


    /**
     * 设置某一列的aline位置
     * @param columnIndex
     * @param aline
     */
    public void setAline(int columnIndex, Layout.Alignment aline){
        this.aline.put(columnIndex,aline);
    }

    /**
     * 清除设置的aline信息
     */
    public void cliearAline(){
        this.aline.clear();
    }

猜你喜欢

转载自blog.csdn.net/sinat_35226205/article/details/81701409