自定义表格控件view

效果图如下

view源码:

public class TableView extends View {
    /**
     * 单元格基准宽度,设权重的情况下,为最小单元格宽度
     */
    private float unitColumnWidth;
    private float rowHeight;
    private float dividerWidth;
    private int dividerColor;
    private float textSize;
    private int textColor;
    private int headerColor;
    private float headerTextSize;
    private int headerTextColor;

    private int rowCount;
    private int columnCount;

    private Paint paint;

    private float[] columnLefts;
    private float[] columnWidths;

    private int[] columnWeights;
    private List<String[]> tableContents;

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

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

    private void init(AttributeSet attrs) {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextAlign(Paint.Align.CENTER);
        tableContents = new ArrayList<>();
        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.TableView);
            unitColumnWidth = typedArray.getDimensionPixelSize(R.styleable.TableView_unitColumnWidth, 0);
            rowHeight = typedArray.getDimensionPixelSize(R.styleable.TableView_rowHeight, AbScreenUtils.dp2px(getContext(), 36));
            dividerWidth = typedArray.getDimensionPixelSize(R.styleable.TableView_dividerWidth, 1);
            dividerColor = typedArray.getColor(R.styleable.TableView_dividerColor, Color.parseColor("#E1E1E1"));
            textSize = typedArray.getDimensionPixelSize(R.styleable.TableView_textSize, AbScreenUtils.dp2px(getContext(), 10));
            textColor = typedArray.getColor(R.styleable.TableView_textColor, Color.parseColor("#999999"));
            headerColor = typedArray.getColor(R.styleable.TableView_headerColor, Color.parseColor("#00ffffff"));
            headerTextSize = typedArray.getDimensionPixelSize(R.styleable.TableView_headerTextSize, AbScreenUtils.dp2px(getContext(), 10));
            headerTextColor = typedArray.getColor(R.styleable.TableView_headerTextColor, Color.parseColor("#999999"));
            typedArray.recycle();
        } else {
            unitColumnWidth = 0;
            rowHeight = AbScreenUtils.dp2px(getContext(), 36);
            dividerWidth = 1;
            dividerColor = Color.parseColor("#E1E1E1");
            textSize = AbScreenUtils.dp2px(getContext(), 10);
            textColor = Color.parseColor("#999999");
            headerColor = Color.parseColor("#00ffffff");
            headerTextSize = AbScreenUtils.dp2px(getContext(), 10);
            headerTextColor = Color.parseColor("#111111");
        }
        setHeader("Header1", "Header2").addContent("Column1", "Column2");
        initTableSize();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        unitColumnWidth = 0;
        //通过权重计算最小单元格宽度
        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;
        }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        calculateColumns();
        drawHeader(canvas);
        drawFramework(canvas);
        drawContent(canvas);
    }

    /**
     * 画表头
     *
     * @param canvas
     */
    private void drawHeader(Canvas canvas) {
        paint.setColor(headerColor);
        canvas.drawRect(dividerWidth, dividerWidth, getWidth() - dividerWidth, rowHeight + dividerWidth, paint);
    }

    /**
     * 画整体表格框架
     */
    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);
        }
        for (int i = 0; i < rowCount + 1; i++) {
            canvas.drawRect(0, i * (rowHeight + dividerWidth), getWidth(), i * (rowHeight + dividerWidth) + dividerWidth, paint);
        }
    }

    /**
     * 画内容
     */
    private void drawContent(Canvas canvas) {
        for (int i = 0; i < rowCount; i++) {
            final String[] rowContent = tableContents.size() > i ? tableContents.get(i) : new String[0];
            if (i == 0) {
                //设置表头文字画笔样式
                paint.setColor(headerTextColor);
                paint.setTextSize(headerTextSize);
            }
            for (int j = 0; j < columnCount; j++) {
                if (rowContent.length > j) {
                    canvas.drawText(rowContent[j],
                            columnLefts[j] + columnWidths[j] / 2,
                            getTextBaseLine(i * (rowHeight + dividerWidth), paint),
                            paint);
                }
            }
            if (i == 0) {
                //恢复表格文字画笔样式
                paint.setColor(textColor);
                paint.setTextSize(textSize);
            }
        }
    }

    /**
     * 计算每列左端坐标及列宽
     */
    private void calculateColumns() {
        columnLefts = new float[columnCount];
        columnWidths = new float[columnCount];
        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;
        }
        int weight = columnWeights.length > columnIndex ? columnWeights[columnIndex] : 1;
        return weight * unitColumnWidth;
    }

    private float getTextBaseLine(float rowStart, Paint paint) {
        final Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        return (rowStart + (rowStart + rowHeight) - fontMetrics.bottom - fontMetrics.top) / 2;
    }

    /**
     * 设置表格内容
     */
    public TableView clearTableContents() {
        columnWeights = null;
        tableContents.clear();
        return this;
    }

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

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

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

    /**
     * 设置表格内容
     */
    public TableView 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();
//         invalidate();
    }

}

使用方法,项目中先添加view控件

 <com.chuanglan.flashchat.view.TableView
        android:id="@+id/table"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rl_chart_title"
        android:layout_centerInParent="true"
        android:layout_margin="8dp"
        app:dividerColor="#e1e1e1"
        app:dividerWidth="1px"
        app:headerColor="#F9F9F9"
        app:headerTextColor="#111111"
        app:headerTextSize="10dp"
        app:rowHeight="36dp"
        app:textColor="#999999"
        app:textSize="10dp" />

表格中设置值:

 tableView.clearTableContents()
                    .setHeader("日期", "启动次数", "活跃用户", "新增用户");
            for (int i = 0; i < item.getRealNameAuthenticationData().size(); i++) {
                AllAppStatisticsBean.RealNameAuthenticationDataDTO realNameAuthenticationDataDTO = item.getRealNameAuthenticationData().get(i);
                tableView.addContent(realNameAuthenticationDataDTO.getAuthenticationDate(), realNameAuthenticationDataDTO.getAuthenticationReuqestCount() + "", realNameAuthenticationDataDTO.getAuthenticationCount() + "", realNameAuthenticationDataDTO.getSuccessRate() + "");
            }

            tableView.refreshTable();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值