把自定义表格又改进了一下,可以支持行合并。表格分为简单和复杂两种模式
1、简单模式就是《Android中使用ListView绘制自定义表格(2)》描述的方式。不支持行合并
2、复杂模式支持行列合并
1、基于上回上传的代码,改动文件如下
package csdn.danielinbiti.custometableview.item;
public class ItemCell {
private String cellValue = "";//单元格的值
private int cellSpan = 1; //单元格跨列
private CellTypeEnum cellType = CellTypeEnum.LABEL; //单元格类型
private int colNum = 0; //单元格列号,从0开始
private int rowNum = 0;//从0开始,每个item都从0开始
private int rowSpan = 1;//单元格跨行
//private int rowType = 0; //行类型
private boolean isChange = false;//是否被编辑
public ItemCell(String cellValue,CellTypeEnum cellType,int cellSpan){
this.cellValue = cellValue;
this.cellType = cellType;
this.cellSpan = cellSpan;
}
public ItemCell(String cellValue, CellTypeEnum cellType){
this(cellValue,cellType,1);
}
public int getColNum(){
return this.colNum;
}
// public void setRowType(int rowType){
// this.rowType = rowType;
// }
// public int getRowType(){
// return this.rowType;
// }
public String getCellValue(){
return cellValue;
}
public void setCellValue(String value){
this.cellValue = value;
}
public CellTypeEnum getCellType(){
return cellType;
}
public int getCellSpan(){
return cellSpan;
}
public void setIsChange(boolean isChange){
this.isChange = isChange;
}
public boolean getIsChange(){
return this.isChange;
}
//设置行列位置,列根据前面列+rowspan数字累加后的值,rownum每行都从0开始
public void setPos(int rowNum,int colNum,int rowSpan){
this.rowNum = rowNum;
this.colNum = colNum;
this.rowSpan = rowSpan;
}
public int getRowNum() {
return rowNum;
}
public int getRowSpan() {
return rowSpan;
}
public int getId(){
return this.rowNum * 10000 + this.rowSpan;
}
}
package csdn.danielinbiti.custometableview.item;
import java.util.ArrayList;
import java.util.HashMap;
import csdn.danielinbiti.custometableview.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
public class CustomeTableItem extends LinearLayout {
private Context context = null;
private boolean isRead = false;//是否只读
private ArrayList<View> viewList = new ArrayList();//行的表格列表
private HashMap<String,View> viewMap = new HashMap();//key为行列组合
private int[] headWidthArr = null;//表头的列宽设置
private String rowType = "0";//行的样式id
private int rowHeight = 0;
private boolean isSimple = true;//是否简单的行模式(没有行合并)
public CustomeTableItem(Context context) {
super(context);
}
public CustomeTableItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomeTableItem(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/*
* rowType:行的样式,字符任意,相同样式的行不需要再创建了
* itemCells:单元格信息
* headWidthArr:每列宽度
* isRead:是否只读,如果是只读,则所有的输入都不生效
*/
public void buildItem(Context context,String rowType,ArrayList<ItemCell> itemCells
,int[] headWidthArr,boolean isRead){
if(this.getTag()!=null
&& this.getTag() instanceof String
&& this.getTag().equals("2")){//设置成2为复杂的行合并
this.isSimple = false;
}
this.setOrientation(LinearLayout.VERTICAL);//第一层布局垂直
this.context = context;
this.headWidthArr =headWidthArr.clone();
this.rowType = rowType;
if(rowHeight==0){
rowHeight = Dp2Px(context,40);
}
if(isSimple){
this.addCell(itemCells);
}else{
this.addCellR(itemCells);
}
}
private void addCell(ArrayList<ItemCell> itemCells){
this.removeAllViews();
LinearLayout secondLayout = new LinearLayout(context);
secondLayout.setOrientation(LinearLayout.HORIZONTAL);
secondLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
this.addView(secondLayout);
int cellIndex = 0;
for(int i=0;i<itemCells.size();i++){
ItemCell itemCell = itemCells.get(i);
int endIndex = cellIndex+itemCell.getCellSpan();//所占行数
int width = getCellWidth(cellIndex,endIndex);//行宽度
cellIndex = endIndex;
if(itemCell.getCellType()==CellTypeEnum.STRING){
EditText view= (EditText)getInputView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
this.setEditView(view);
secondLayout.addView(view);
viewList.add(view);
}else if(itemCell.getCellType()==CellTypeEnum.DIGIT){
EditText view= (EditText)getInputView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
this.setEditView(view);
this.setOnKeyBorad(view);
secondLayout.addView(view);
viewList.add(view);
}else if(itemCell.getCellType()==CellTypeEnum.LABEL){
TextView view = (TextView)getLabelView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
secondLayout.addView(view);
viewList.add(view);
}
if(i!=itemCells.size()-1){//插入竖线
LinearLayout v_line = (LinearLayout)getVerticalLine();
v_line.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
secondLayout.addView(v_line);
}
}
}
private void addCellR(ArrayList<ItemCell> itemCells){
this.removeAllViews();
RelativeLayout secondLayout = new RelativeLayout(context);
//secondLayout.setOrientation(LinearLayout.HORIZONTAL);
secondLayout.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
this.addView(secondLayout);
//int cellIndex = 0;
for(int i=0;i<itemCells.size();i++){
ItemCell itemCell = itemCells.get(i);
int endIndex = itemCell.getColNum()+itemCell.getCellSpan();//所占行数
int width = getCellWidth(itemCell.getColNum(),endIndex);//行宽度
int height = getCellHeight(itemCell.getRowSpan());
int left = this.getCellLeft(itemCell.getColNum());
int top = this.getCellTop(itemCell.getRowNum());
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
rl.leftMargin = left;
rl.topMargin = top;
if(itemCell.getCellType()==CellTypeEnum.STRING){
EditText view= (EditText)getInputView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
view.setHeight(height);
this.setEditView(view);
secondLayout.addView(view,rl);
viewMap.put(itemCell.getId()+"", view);
}else if(itemCell.getCellType()==CellTypeEnum.DIGIT){
EditText view= (EditText)getInputView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
view.setHeight(height);
this.setEditView(view);
this.setOnKeyBorad(view);
secondLayout.addView(view,rl);
viewMap.put(itemCell.getId()+"", view);
}else if(itemCell.getCellType()==CellTypeEnum.LABEL){
TextView view = (TextView)getLabelView();
view.setText(itemCell.getCellValue());
view.setWidth(width);
view.setHeight(height);
secondLayout.addView(view,rl);
viewMap.put(itemCell.getId()+"", view);
}
// if(i!=itemCells.size()-1){//插入竖线
// LinearLayout v_line = (LinearLayout)getVerticalLine();
// v_line.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
// secondLayout.addView(v_line);
// }
}
}
public void refreshData(ArrayList<ItemCell> itemCells){
if(this.isSimple){
this.refreshDataSimple(itemCells);
}else{
this.refreshDataR(itemCells);
}
}
private void refreshDataSimple(ArrayList<ItemCell> itemCells){
for(int i=0;i<itemCells.size();i++){
ItemCell itemCell = itemCells.get(i);
if(itemCell.getCellType()==CellTypeEnum.LABEL){
TextView view = (TextView)viewList.get(i);
view.setText(itemCell.getCellValue());
}else if(itemCell.getCellType()==CellTypeEnum.DIGIT){
EditText view= (EditText)viewList.get(i);
view.setText(itemCell.getCellValue());
this.setEditView(view);
this.setOnKeyBorad(view);
}else if(itemCell.getCellType()==CellTypeEnum.STRING){
EditText view= (EditText)viewList.get(i);
view.setText(itemCell.getCellValue());
this.setEditView(view);
}
}
}
private void refreshDataR(ArrayList<ItemCell> itemCells){
for(int i=0;i<itemCells.size();i++){
ItemCell itemCell = itemCells.get(i);
if(itemCell.getCellType()==CellTypeEnum.LABEL){
TextView view = (TextView)viewMap.get(itemCell.getId()+"");
view.setText(itemCell.getCellValue());
}else if(itemCell.getCellType()==CellTypeEnum.DIGIT){
EditText view= (EditText)viewMap.get(itemCell.getId()+"");;
view.setText(itemCell.getCellValue());
this.setEditView(view);
this.setOnKeyBorad(view);
}else if(itemCell.getCellType()==CellTypeEnum.STRING){
EditText view= (EditText)viewMap.get(itemCell.getId()+"");;
view.setText(itemCell.getCellValue());
this.setEditView(view);
}
}
}
private View getVerticalLine(){
return LayoutInflater.from(context).inflate(R.layout.atom_line_v_view, null);
}
private int getCellWidth(int cellStart,int cellEnd){
int width = 0;
for(int i=cellStart;i<cellEnd;i++){
width = this.headWidthArr[i] + width;
}
return width;
}
private int getCellLeft(int cellIndex){//从0开始编号
int left = 0;
for(int i=0;i<cellIndex;i++){
left = this.headWidthArr[i] + left;
}
return left;
}
private int getCellTop(int rowNum){ //rowNum从0开始
return rowNum*this.rowHeight;
}
private int Dp2Px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
private int getCellHeight(int rowSpan){
return rowSpan * this.rowHeight;
}
private View getLabelView(){
return (View)LayoutInflater.from(context).inflate(R.layout.atom_text_view, null);
}
private View getInputView(){
return (View)LayoutInflater.from(context).inflate(R.layout.atom_edttxt_view, null);
}
private void setEditView(EditText edtText1){
if(this.isRead){
edtText1.setEnabled(false);
}else{
}
}
private void setOnKeyBorad(EditText edtText1){
//数字键盘
if(!this.isRead){//非只读
}
}
public String getRowType() {
return rowType;
}
}
<?xml version="1.0" encoding="utf-8"?>
<csdn.danielinbiti.custometableview.item.CustomeTableItem android:id="@+id/custome_item"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:tag="1"
android:gravity="center_vertical"
/>3、测试数据格式
private void testAddContentRows(HashMap contentMap){
HashMap rowMap1 = new HashMap();
lists.add(rowMap1);
this.testAddRows(rowMap1, 1, "r1-1-1(1)", CellTypeEnum.LABEL,0,0,1);
this.testAddRows(rowMap1, 1, "r1-2-1(1)", CellTypeEnum.LABEL,1,0,1);
this.testAddRows(rowMap1, 1, "r1-1-2(1)", CellTypeEnum.STRING,0,1,2);
this.testAddRows(rowMap1, 2, "r1-1-3(2)", CellTypeEnum.STRING,0,2,2);
this.testAddRows(rowMap1, 1, "r1-1-4(1)", CellTypeEnum.DIGIT,0,4,2);//注意这个列号的标识,必须是前面列号+跨行数
rowMap1.put("rowtype", "css1");//表样标示放在内容添加后再添加
HashMap rowMap2 = new HashMap();
lists.add(rowMap2);
this.testAddRows(rowMap2, 1, "r2-1-1(1)", CellTypeEnum.LABEL,0,0,1);
this.testAddRows(rowMap2, 1, "r2-2-1(1)", CellTypeEnum.LABEL,1,0,1);
this.testAddRows(rowMap2, 1, "r2-1-2(2)", CellTypeEnum.STRING,0,1,2);
this.testAddRows(rowMap2, 2, "r2-1-3(1)", CellTypeEnum.STRING,0,2,1);
this.testAddRows(rowMap2, 2, "r2-2-3(1)", CellTypeEnum.STRING,1,2,1);
this.testAddRows(rowMap2, 1, "r2-1-4(1)", CellTypeEnum.DIGIT,0,4,2);
rowMap2.put("rowtype", "css2");//表样标示放在内容添加后再添加
HashMap rowMap3 = new HashMap();
lists.add(rowMap3);
this.testAddRows(rowMap3, 1, "r3-1-1(1)", CellTypeEnum.LABEL,0,0,1);
this.testAddRows(rowMap3, 1, "r3-2-1(1)", CellTypeEnum.LABEL,1,0,1);
this.testAddRows(rowMap3, 1, "r3-2-1(1)", CellTypeEnum.LABEL,2,0,1);
this.testAddRows(rowMap3, 1, "r3-1-2(2)", CellTypeEnum.STRING,0,1,3);
this.testAddRows(rowMap3, 2, "r3-1-3(1)", CellTypeEnum.STRING,0,2,1);
this.testAddRows(rowMap3, 2, "r3-2-3(1)", CellTypeEnum.STRING,1,2,1);
this.testAddRows(rowMap3, 2, "r3-2-3(1)", CellTypeEnum.STRING,2,2,1);
this.testAddRows(rowMap3, 1, "r3-1-4(1)", CellTypeEnum.DIGIT,0,4,3);
rowMap3.put("rowtype", "css3");//表样标示放在内容添加后再添加
HashMap rowMap4 = new HashMap();
lists.add(rowMap4);
this.testAddRows(rowMap4, 1, "r4-1-1(1)", CellTypeEnum.LABEL,0,0,1);
this.testAddRows(rowMap4, 1, "r4-2-1(1)", CellTypeEnum.LABEL,1,0,1);
this.testAddRows(rowMap4, 1, "r4-2-1(1)", CellTypeEnum.LABEL,2,0,1);
this.testAddRows(rowMap4, 1, "r4-1-2(2)", CellTypeEnum.STRING,0,1,3);
this.testAddRows(rowMap4, 2, "r4-1-3(1)", CellTypeEnum.STRING,0,2,1);
this.testAddRows(rowMap4, 2, "r4-2-3(1)", CellTypeEnum.STRING,1,2,1);
this.testAddRows(rowMap4, 2, "r4-2-3(1)", CellTypeEnum.STRING,2,2,1);
this.testAddRows(rowMap4, 1, "r4-1-4(1)", CellTypeEnum.DIGIT,0,4,3);
rowMap4.put("rowtype", "css3");//表样标示放在内容添加后再添加
}private void testAddRows(HashMap rowMap,int colSpan,String cellValue,CellTypeEnum cellType,int rowNum,int colNum,int rowSpan){
ItemCell itemCell = new ItemCell(cellValue,cellType,colSpan);
itemCell.setPos(rowNum, colNum, rowSpan);
rowMap.put(rowMap.size()+"", itemCell);
}//this.testAddContent(contentMap);//简单模式,原来的代码,改行替换成下面代码就可以 this.testAddContentRows(contentMap);//复杂模式
建议对于最好弄个简单的html之类的布局设计器,这样生成能够使用的数据相对比较好点,要不人工计算数据很容易出错。
源码参见自定义表格(2) ,改动的代码已经在上面都贴出来了。
原文:http://blog.csdn.net/danielinbiti/article/details/38927669