Android中使用ListView绘制自定义表格技巧分享
Android中使用ListView绘制自定义表格技巧分享
发布时间:2017-01-07 来源:查字典编辑
摘要:先上一下可以实现的效果图要实现的效果有几方面1、列不固定:可以根据数据源的不同生成不同的列数2、表格内容可以根据数据源的定义合并列3、要填写...

先上一下可以实现的效果图

1

要实现的效果有几方面

1、列不固定:可以根据数据源的不同生成不同的列数

2、表格内容可以根据数据源的定义合并列

3、要填写的单元格可以选择自定义键盘还是系统键盘

奔着这三点,做了个简单的实现,把源码贴一下(因为该点是主界面中的一部分,不便于放整个Demo)

自定义适配器,CallBackInterface是自定义的回调接口,这里定义回调是因为数据输入时需要及时保存

复制代码 代码如下:

public class SiteDetailViewAdapter extends BaseAdapter implements CallBackInterface{

private Context context;

private LayoutInflater inflater;

private ArrayList<HashMap<String,Object>> lists;

private KeyBoard keyBoard = null;//自定义键盘

private ListView listView = null;

private boolean isReadOnly = false;//是否是浏览状态

private String[] arrCellType = null;

private int[] arrHeadWidth = null;//每列宽度

public SiteDetailViewAdapter(Context context, ArrayList<HashMap<String,Object>> lists

,KeyBoard keyBoard,ListView listView,boolean isReadOnly

,int[] arrHeadWidth) {

super();

this.context = context;

this.lists = lists;

inflater = LayoutInflater.from(context);

this.keyBoard = keyBoard;

this.listView = listView;

this.isReadOnly = isReadOnly;

this.arrHeadWidth = arrHeadWidth;

this.listView.setAdapter(this);

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return lists.size();

}

@Override

public Object getItem(int arg0) {

// TODO Auto-generated method stub

return arg0;

}

@Override

public long getItemId(int arg0) {

// TODO Auto-generated method stub

return arg0;

}

@Override

public View getView(int index, View view, ViewGroup arg2) {

HashMap map = lists.get(index);

String type = (String)map.get("rowtype");

ArrayList<ItemCell> itemCells = new ArrayList();

//String cellValue,String cellKey,long cellType,int cellInRow,int cellSpan

ItemCell itemCellXuHao = new ItemCell((index+1)+"","-1",1,-1,1);

itemCells.add(itemCellXuHao);

for(int i=0;i<map.size()-1;i++){

ItemCell itemCell = (ItemCell)map.get(i+"");

itemCells.add(itemCell);

}

//性能优化后需要放开注释danielinbiti

if(view == null||view!=null&&!((ListItemCustom)view.getTag()).getType().equals(type)){

view = inflater.inflate(R.layout.customel_list_item, null);

ListItemCustom itemCustom = (ListItemCustom)view.findViewById(R.id.custome_item);

itemCustom.buildItem(type, context, isReadOnly,arrHeadWidth,itemCells,index

,this.listView,this.keyBoard,this);

view.setTag(itemCustom);

}else{

ListItemCustom itemCustom = (ListItemCustom)view.getTag();

itemCustom.refreshData(itemCells,index);

}

if(index%2 == 0){

view.setBackgroundColor(Color.argb(250 , 255 , 255 , 255 ));

}else{

view.setBackgroundColor(Color.argb(250 , 224 , 243 , 250 ));

}

return view;

}

@Override

public boolean exectueMethod(Object params) {

String[] arr = (String[])params;

HashMap map = lists.get(Integer.parseInt(arr[0]));

ItemCell itemCell = (ItemCell)map.get(arr[1]);

itemCell.setCellValue(arr[2]);

itemCell.setIsChange(true);

return false;

}

ListView每行的布局,内部代码是有冗余的,因为是Demo,所以先以效果未准,未进行代码重构,注意不能往ListItemCustom中传入每行的Map来进行值得获取或者输入更新等操作,因为Map是按地址方式,再结合ListView的绘制方式,最终的map不是你想象的map。

复制代码 代码如下:

public class ListItemCustom extends LinearLayout{

public ListItemCustom(Context context){

super(context);

}

public ListItemCustom(Context context, AttributeSet attrs) {

super(context, attrs);

}

private String type = "-1";

private Context context = null;

private boolean isRead = false;

private int[] headWidthArr = null;

private ListView listView = null;

private KeyBoard keyBoard = null;

private int orderNum = -1;

private ArrayList<View> viewList = new ArrayList();

private int rowNum = -1;

private CallBackInterface callBack = null;

public void buildItem(String type,Context context,boolean isRead,int[] headWidthArr

,ArrayList<ItemCell> itemCells,int rowNum

,ListView listView,KeyBoard keyBoard,CallBackInterface callBack){

this.context = context;

this.isRead = isRead;

this.headWidthArr = headWidthArr;

this.setOrientation(LinearLayout.VERTICAL);

this.rowNum = rowNum;

this.listView = listView;

this.keyBoard = keyBoard;

this.callBack = callBack;

this.type = type;

this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,45));

this.addCell(itemCells);

}

public void refreshData(ArrayList<ItemCell> itemCells,int rowNum){

this.rowNum = rowNum;

this.refreshCells(itemCells);

}

private void refreshCells(ArrayList<ItemCell> itemCells){

for(int i=0;i<itemCells.size();i++){

ItemCell itemCell = itemCells.get(i);

if(itemCell.getCellType()==ItemCellValueType.VALUE_NONE){

TextView view = (TextView)viewList.get(i);

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

}else if(itemCell.getCellType()==ItemCellValueType.VALUE_NUMBER){

EditText view= (EditText)viewList.get(i);

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

//view.setText(itemCell.getCellId()+"");

//view.setTag(itemCell.getCellKey()+"");

this.setEditView(view,itemCell.getCellKey());

this.setOnKeyBorad(view, itemCell.getCellInRow());

}else if(itemCell.getCellType()==ItemCellValueType.VALUE_STRING){

EditText view= (EditText)viewList.get(i);

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

//view.setText(itemCell.getCellId()+"");

//view.setTag(itemCell.getCellKey()+"");

this.setEditView(view,itemCell.getCellKey());

}

}

}

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 void addCell(ArrayList<ItemCell> itemCells){

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()==ItemCellValueType.VALUE_NONE){

TextView view = (TextView)getReadView();

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

view.setWidth(width);

secondLayout.addView(view);

viewList.add(view);

}else if(itemCell.getCellType()==ItemCellValueType.VALUE_NUMBER){

EditText view= (EditText)getInputView();

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

view.setWidth(width);

//view.setText(itemCell.getCellId()+"");

//view.setTag(itemCell.getCellKey()+"");

this.setEditView(view,itemCell.getCellKey());

this.setOnKeyBorad(view, itemCell.getCellInRow());

secondLayout.addView(view);

viewList.add(view);

}else if(itemCell.getCellType()==ItemCellValueType.VALUE_STRING){

EditText view= (EditText)getInputView();

view.setId(itemCell.getCellId());

view.setText(itemCell.getCellValue());

view.setWidth(width);

//view.setText(itemCell.getCellId()+"");

//view.setTag(itemCell.getCellKey()+"");

this.setEditView(view,itemCell.getCellKey());

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 View getVerticalLine(){

return LayoutInflater.from(context).inflate(R.layout.atom_line_v_view, null);

}

private View getReadView(){

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 setOnKeyBorad(EditText edtText1,int index){

if(!this.isRead){

onListenText(edtText1,this.listView,index);

}

}

private void onListenText(EditText edtText,ListView listView,int index){

final ListView lsv = listView;

final int idx = index;

edtText.setOnFocusChangeListener(new OnFocusChangeListener(){

@Override

public void onFocusChange(View arg0, boolean arg1) {

if(arg1){

int[] y = getYPos(lsv,idx);

keyBoard.show((EditText)arg0,y[0],y[1]);

}

}

});

}

private int[] getYPos(ListView listview,int index){

int[] yPosArr = new int[2];

Rect r = new Rect();

listview.getChildAt(0).getGlobalVisibleRect(r);

int first = listview.getFirstVisiblePosition();

yPosArr[1] = (index-first+1)*r.height()+listview.getTop();

yPosArr[0] = (index-first)*r.height()+listview.getTop();

return yPosArr;

}

private void setEditView(EditText edtText1,final String key){

if(this.isRead){

edtText1.setEnabled(false);

}else{

edtText1.addTextChangedListener(new TextWatcher() {

@Override

public void afterTextChanged(Editable arg0) {

String[] arr = new String[3];

arr[0] = rowNum+"";

arr[1] = key;

arr[2] = arg0.toString();

callBack.exectueMethod(arr);

// ItemCell itemCell = (ItemCell)dataMap.get(key);

// itemCell.setCellValue(arg0.toString());

// itemCell.setIsChange(true);

}

@Override

public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,

int arg3) {

}

@Override

public void onTextChanged(CharSequence arg0, int arg1, int arg2,

int arg3) {

}

});

}

}

public String getType(){

return this.type;

}

}

复制代码 代码如下:

public class ItemCell {

private String cellValue = "";

private int cellSpan = 1;

private String cellKey = "";

private int cellInRow = 0;

private long cellType = ItemCellValueType.VALUE_NONE;

private int colNum = 0;

private int rowType = 0;

private int cellId = -1;

private boolean isValueFromTable = false;

private boolean isChange = false;

public ItemCell(String cellValue,String cellKey,long cellType,int cellInRow,int cellSpan){

this.cellValue = cellValue;

this.cellType = cellType;

this.cellSpan = cellSpan;

this.cellKey = cellKey;

this.cellInRow = cellInRow;

}

public ItemCell(String cellValue,String cellKey,long cellType,int cellInRow){

this(cellValue,cellKey,cellType,cellInRow,1);

}

public void setColNum(int colNum){

this.colNum = colNum;

}

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 long getCellType(){

return cellType;

}

public int getCellSpan(){

return cellSpan;

}

public String getCellKey(){

return cellKey;

}

public int getCellInRow(){

return cellInRow;

}

public void setIsChange(boolean isChange){

this.isChange = isChange;

}

public boolean getIsChange(){

return this.isChange;

}

public int getCellId() {

return cellId;

}

public void setCellId(int cellId) {

this.cellId = cellId;

}

public boolean isValueFromTable() {

return isValueFromTable;

}

public void setValueFromTable(boolean isValueFromTable) {

this.isValueFromTable = isValueFromTable;

}

}

custome_list_item.xml文件

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="40dp"

android:orientation="vertical"

android:id="@+id/test_dajej"

android:background="#ffffff">

<srit.collection.widget.costomtable.ListItemCustom android:id="@+id/custome_item"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

/>

</LinearLayout>

以上是核心的文件内容。有了列合并,行合并也不远了。可以在自定义的布局中多加个LinearLayout来实现行合并。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新安卓软件开发学习
热门安卓软件开发学习
编程开发子分类