需求描述:
需要一个table,要求如下:
1.有表格线
2.标题的颜色,背景色,每行的颜色,背景色,框线色可随意设置
3.当当前格子的内容多时,自动挤压其他格子不会遮挡;当前格子内容少时居中,多于一行时居左。

效果:

简易自定义table_android


自定义控件:

package com.dyy.yonxin.library2.test.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

/**
* Created by 段钰莹 on 2017/11/27.
*/


public class MyTable extends TableLayout
public MyTable(Context context) {
super(context);
}

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

@Override
protected void onFinishInflate() {
super.onFinishInflate();
}

private int headTxtColor=0xff000000;
public void setHeadColor(int headColor){
this.headTxtColor = headColor;
}

private int headBackground=0xffffffff;
public void setHeadBackground(int headBackground){
this.headBackground = headBackground;
}

private int headPadding = 50;
public void setHeadPadding(int headPadding){
this.headPadding = headPadding;
}

private int dividerSize = 1;
private int dividerColor = 0xff000000;
public void setDivider(int size, int color){
this.dividerColor = color;
this.dividerSize = size;
}

private int contentTxtColor = 0xff000000;
public void setContentTxtColor(int contentTxtColor){
this.contentTxtColor = contentTxtColor;
}

public int contentBackground = 0xffffffff;
public void setContentBackground(int background){
this.contentBackground = contentBackground;
}

private int contentPadding = 50;
public void setContentPadding(int contentPadding){
this.contentPadding = contentPadding;
}

private int getScreenWidth(){
WindowManager wm = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);

int width = wm.getDefaultDisplay().getWidth();
return width;
}

public void addHeader(String...header){
addDividerLine();
TableRow tabRow = new TableRow(getContext());
addView(tabRow);
addDividerCol(tabRow);

for(int i = 0; i < header.length; i++){
TextView tv = new TextView(getContext());
tv.setBackgroundColor(headBackground);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(headTxtColor);
tv.setText(header[i]);
tv.setTextSize(12);
tv.setMaxWidth(getScreenWidth()/header.length);
tv.setPadding(headPadding,headPadding,headPadding,headPadding);
tabRow.addView(tv);
TableRow.LayoutParams params = (TableRow.LayoutParams) tv.getLayoutParams();
params.weight = 1;
tv.setLayoutParams(params);
addDividerCol(tabRow);
}
addDividerLine();
}

public void addContent(String...content){
TableRow tabRow = new TableRow(getContext());
addView(tabRow);
addDividerCol(tabRow);
for(int i = 0; i < content.length; i++){
final TextView tv = new TextView(getContext());
tv.setBackgroundColor(contentBackground);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(contentTxtColor);
tv.setText(content[i]);
tv.setTextSize(12);
tv.setPadding(contentPadding,contentPadding,contentPadding,contentPadding);
tv.setMaxWidth(getScreenWidth()/content.length);
tv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
//这个回调会调用多次,获取完行数记得注销监听
tv.getViewTreeObserver().removeOnPreDrawListener(this);
if(tv.getLineCount()>1)
tv.setGravity(Gravity.LEFT);
return false;
}
});
tabRow.addView(tv);
TableRow.LayoutParams params = (TableRow.LayoutParams) tv.getLayoutParams();
params.weight = 1;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
tv.setLayoutParams(params);
addDividerCol(tabRow);
}
addDividerLine();
}

private int width = 0;
private int height = 0;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = widthMeasureSpec;
height = heightMeasureSpec;
}

private void addDividerCol(TableRow tableRow) {
TextView dividerCol = new TextView(getContext());
dividerCol.setBackgroundColor(dividerColor);
tableRow.addView(dividerCol);
TableRow.LayoutParams params = (TableRow.LayoutParams) dividerCol.getLayoutParams();
params.width = dividerSize;
params.height = LayoutParams.MATCH_PARENT;
dividerCol.setLayoutParams(params);
}

private void addDividerLine() {
TextView dividerLine = new TextView(getContext());
dividerLine.setBackgroundColor(dividerColor);
addView(dividerLine);
MyTable.LayoutParams params = (LayoutParams) dividerLine.getLayoutParams();
params.width = LayoutParams.MATCH_PARENT;
params.height = dividerSize;
dividerLine.setLayoutParams(params);
}

public void clear() {
removeViews(0,getChildCount());
}
}

使用:
1.在布局中加入控件:

<com.dyy.yonxin.library2.test.view.MyTable android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
xmlns:android="http://schemas.android.com/apk/res/android">

</com.dyy.yonxin.library2.test.view.MyTable>

2.使用:

.id.table);
table.setHeadBackground(Color.BLUE);
table.setHeadColor(Color.WHITE);
table.clear();
table.addHeader("颜色","型号");
table.addContent("白色","GSOVD-234bGSOVD-234bGSOVD-234bGSOVD-234bGSOVD-234bGSOVD-234bGSOVD-234bGSOVD-234b");
table.addContent("白色","GSOVD-234b");
table.addContent("白色","GSOVD-234b");
table.addContent("白色","GSOVD-234b");
table.addContent("白色","GSOVD-234b");

注意,代码中能够自动挤压的关键是:

tv.setMaxWidth(getScreenWidth()/content.length);
TableRow.LayoutParams params = (TableRow.LayoutParams) tv.getLayoutParams();
params.weight = 1;
tv.setLayoutParams(params);

当然你也可以在onDraw时候写,这样可以直接:
tv.setMaxWidth(getWidth()/content.length);

setMaxWidth不会导致当前格子最多只有你设置的那么宽,但是能够保证不会占据全部位置,给其他格子留下空间。