Android 使用TableLayout动态绘制表格
第一步:在layout文件中添加TableLayout
在layout文件中添加TableLayout组件,其中添加两行TableRow,绘制表格标题和表格列的名称。
在需要分格的TableRow中添加LinearLayout, , 再在LinearLayout中添加TextView, 便于使用weight属性调整每一格的宽度。
其中android:stretchColumns="*"
属性使每一行内的控件自动拉伸填充表格行。
由于TableLayout没有设置边框颜色的属性, 于是使用android:background="@color/black"
将背景设置为想要设置的边框颜色, 然后在TableRow中添加背景填充, 使得TableLayout的背景颜色以margin的形式显示出来, 形成表格边框的样式。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TableLayout
android:id="@+id/tableLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="@color/black"
android:stretchColumns="*">
<TableRow
android:id="@+id/tRowTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:background="@color/white">
<TextView
android:id="@+id/tvTableTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="TableTitle"
android:textSize="20sp" />
</TableRow>
<TableRow
android:id="@+id/tRowColumTitle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="horizontal">
<TextView
android:id="@+id/tvColumNo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginRight="1dp"
android:layout_marginBottom="2dp"
android:layout_weight="1"
android:background="@color/white"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="序号"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvColumAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_marginBottom="2dp"
android:layout_weight="4"
android:background="@color/white"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="地址"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvColumLL"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_marginBottom="2dp"
android:layout_weight="2"
android:background="@color/white"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="经纬度"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvColumDistance"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="2dp"
android:layout_marginBottom="2dp"
android:layout_weight="2"
android:background="@color/white"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="距离"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</TableRow>
</TableLayout>
</RelativeLayout>
绘制完成后, 是这个样子
![](https://img2022.cnblogs.com/blog/2371230/202211/2371230-20221114110606296-1999218066.png)
第二步: 创建表格数据对应的类
新建一个类, 用于保存即将填入表格中的每一条数据的信息。
public class DataItem {
private String address, LL, distance;
public DataItem(String address, String LL, String distance) {
this.address = address;
this.LL = LL;
this.distance = distance;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getLL() {
return LL;
}
public void setLL(String LL) {
this.LL = LL;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
}
第三步: 在Activity文件中动态添加表格行
在OnCreate()中添加数据
// 声明变量
TableLayout tableLayout;
private List<DataItem> dataItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 添加要显示的数据
dataItems.add(new DataItem("翻斗大街翻斗花园2号楼1001室", "(64, 52)", "97"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
//绘制表格
initTable();
}
绘制表格
private void initTable() {
tableLayout = findViewById(R.id.tableLayout);
int padding = dip2px(getApplicationContext(), 5);
// 遍历dataItems, 每一条数据都加进TableLayout中
for(int i = 0; i<dataItems.size(); i++){
// 获取一条数据
DataItem dataItem = dataItems.get(i);
// 新建一个TableRow并设置样式
TableRow newRow = new TableRow(getApplicationContext());
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams();
newRow.setLayoutParams(layoutParams);
//新建一个LinearLayout
LinearLayout linearLayout = new LinearLayout(getApplicationContext());
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
// 底部边框的宽度
int bottomLine = dip2px(getApplicationContext(), 1);
if(i == dataItems.size() - 1) {
// 如果当前行是最后一行, 则底部边框加粗
bottomLine = dip2px(getApplicationContext(), 2);
}
// 第一列
TextView tvNo = new TextView(getApplicationContext());
// 设置文字居中
tvNo.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvNo.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpNo = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f);
lpNo.setMargins(dip2px(getApplicationContext(), 2), 0, dip2px(getApplicationContext(), 1), bottomLine);
tvNo.setLayoutParams(lpNo);
// 设置padding和背景颜色
tvNo.setPadding(padding, padding, padding, padding);
tvNo.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvNo.setText((i+1) + "");
// 第二列
TextView tvAddress = new TextView(getApplicationContext());
// 设置文字居中
tvAddress.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpAd = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 4f);
lpAd.setMargins(0, 0, dip2px(getApplicationContext(), 1), bottomLine);
tvAddress.setLayoutParams(lpAd);
// 设置padding和背景颜色
tvAddress.setPadding(padding, padding, padding, padding);
tvAddress.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvAddress.setText(dataItem.getAddress());
// 第三列
TextView tvLL = new TextView(getApplicationContext());
// 设置文字居中
tvLL.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpLL = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 2f);
lpLL.setMargins(0, 0, dip2px(getApplicationContext(), 1), bottomLine);
tvLL.setLayoutParams(lpLL);
// 设置padding和背景颜色
tvLL.setPadding(padding, padding, padding, padding);
tvLL.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvLL.setText(dataItem.getLL());
// 第四列
TextView tvDistance = new TextView(getApplicationContext());
// 设置文字居中
tvDistance.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpDistance = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 2f);
lpDistance.setMargins(0, 0, dip2px(getApplicationContext(), 2), bottomLine);
tvDistance.setLayoutParams(lpDistance);
// 设置padding和背景颜色
tvDistance.setPadding(padding, padding, padding, padding);
tvDistance.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvDistance.setText(dataItem.getDistance());
// 将所有新的组件加入到对应的视图中
linearLayout.addView(tvNo);
linearLayout.addView(tvAddress);
linearLayout.addView(tvLL);
linearLayout.addView(tvDistance);
newRow.addView(linearLayout);
tableLayout.addView(newRow);
}
}
由于new LayoutParams(width,height)
其中的width和height的单位是px,不是dp,所以需要写一个函数px2dip(Context , dpValue)
来进行进行转换px和dp的值。
private int dip2px(Context context, int dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
最后完整的MainActivity代码为
public class MainActivity extends AppCompatActivity {
// 声明变量
TableLayout tableLayout;
private ArrayList<DataItem> dataItems = new ArrayList<DataItem>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 添加要显示的数据
dataItems.add(new DataItem("翻斗大街翻斗花园2号楼1001室", "(64, 52)", "97"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
dataItems.add(new DataItem("地址", "(25, 46)", "79"));
// 绘制表格
initTable();
}
private void initTable() {
tableLayout = findViewById(R.id.tableLayout);
int padding = dip2px(getApplicationContext(), 5);
// 遍历dataItems, 每一条数据都加进TableLayout中
for(int i = 0; i<dataItems.size(); i++){
// 获取一条数据
DataItem dataItem = dataItems.get(i);
// 新建一个TableRow并设置样式
TableRow newRow = new TableRow(getApplicationContext());
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams();
newRow.setLayoutParams(layoutParams);
//新建一个LinearLayout
LinearLayout linearLayout = new LinearLayout(getApplicationContext());
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
// 底部边框的宽度
int bottomLine = dip2px(getApplicationContext(), 1);
if(i == dataItems.size() - 1) {
// 如果当前行是最后一行, 则底部边框加粗
bottomLine = dip2px(getApplicationContext(), 2);
}
// 第一列
TextView tvNo = new TextView(getApplicationContext());
// 设置文字居中
tvNo.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvNo.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpNo = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f);
lpNo.setMargins(dip2px(getApplicationContext(), 2), 0, dip2px(getApplicationContext(), 1), bottomLine);
tvNo.setLayoutParams(lpNo);
// 设置padding和背景颜色
tvNo.setPadding(padding, padding, padding, padding);
tvNo.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvNo.setText((i+1) + "");
// 第二列
TextView tvAddress = new TextView(getApplicationContext());
// 设置文字居中
tvAddress.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpAd = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 4f);
lpAd.setMargins(0, 0, dip2px(getApplicationContext(), 1), bottomLine);
tvAddress.setLayoutParams(lpAd);
// 设置padding和背景颜色
tvAddress.setPadding(padding, padding, padding, padding);
tvAddress.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvAddress.setText(dataItem.getAddress());
// 第三列
TextView tvLL = new TextView(getApplicationContext());
// 设置文字居中
tvLL.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpLL = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 2f);
lpLL.setMargins(0, 0, dip2px(getApplicationContext(), 1), bottomLine);
tvLL.setLayoutParams(lpLL);
// 设置padding和背景颜色
tvLL.setPadding(padding, padding, padding, padding);
tvLL.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvLL.setText(dataItem.getLL());
// 第四列
TextView tvDistance = new TextView(getApplicationContext());
// 设置文字居中
tvDistance.setGravity(Gravity.CENTER);
// 设置表格中的数据不自动换行
tvAddress.setSingleLine();
// 设置边框和weight
LinearLayout.LayoutParams lpDistance = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 2f);
lpDistance.setMargins(0, 0, dip2px(getApplicationContext(), 2), bottomLine);
tvDistance.setLayoutParams(lpDistance);
// 设置padding和背景颜色
tvDistance.setPadding(padding, padding, padding, padding);
tvDistance.setBackgroundColor(Color.parseColor("#FFFFFF"));
// 填充文字数据
tvDistance.setText(dataItem.getDistance());
// 将所有新的组件加入到对应的视图中
linearLayout.addView(tvNo);
linearLayout.addView(tvAddress);
linearLayout.addView(tvLL);
linearLayout.addView(tvDistance);
newRow.addView(linearLayout);
tableLayout.addView(newRow);
}
}
private int dip2px(Context context, int dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
运行结果
![](https://img2022.cnblogs.com/blog/2371230/202211/2371230-20221114110632190-818524253.png)