1、适配器适配的是数据而不是样式
在我们Android 入门学习时,通过ListView,Gallery和Spinner等组件接触到适配器,然后通过自定义的适配器可以使组件变得多种多样,更加灵活。但是和通过getView()显示数据,适配器更重要的是处理不同的数据源,包括变化的。
当我们面临处理样式多样性的需求时,无论样式是怎样的多种多样,但实际上样式都是UI设计好的,固定的。那么很自然的直接将样式写成XML,直接呈现在视图上更加直接。
那么我们为什么要用适配器,为什么借助ListView等组件,为什么通过getView()显示数据?是因为我们面临处理数据的结构和数量多样性的需求。而这在我们入门学习时,往往无论什么适配器,都是用ArrayList储存数据和提取数据,更多的精力放在组件的样式。问题是,数据仅仅用ArrayList结构不足以表示所有的数据形式。因此我们需要不同的自定义的适配器适应不同的结构的数据。
2、学会自定义数据的组织结构
数据结构是我们的入门课,里面有许多成熟的数据结构,数据存储形式,而且大部分语言都定义遍历它们,操作他们的方法。只是实际的需求是多种多样的(UI上数据结构),往往不需要我们使用复杂的数据结构,更多的是根据某些数据结构和面向对象的思想,定义自己的简单的结构。
假如我们定义一个表格的数据结构。我们可以像链表一样,先定义node类,再定义LinkList类一样,先定义Cell类,再定义Item类,最后定义整个table类。
ItemCell.java
package com.work.gongchenglion.unity;
public class ItemCell {
private String cellValue = "";//单元格的值
private CellTypeEnum cellType = CellTypeEnum.LABEL; //单元格类型
private int colNum = 0; //单元格列号
private boolean isChange = false;//是否被编辑
public ItemCell(String cellValue,CellTypeEnum cellType){
this.cellValue = cellValue;
this.cellType = cellType;
}
public void setColNum(int colNum){
this.colNum = colNum;
}
public int getColNum(){
return this.colNum;
}
public String getCellValue(){
return cellValue;
}
public void setCellValue(String value){
this.cellValue = value;
}
public CellTypeEnum getCellType(){
return cellType;
}
public void setIsChange(boolean isChange){
this.isChange = isChange;
}
public boolean getIsChange(){
return this.isChange;
}
}
特殊的Item类:HeadItemCell
package com.work.gongchenglion.unity;
public class HeadItemCell extends ItemCell{
private int width = 0;//单位dp
public HeadItemCell(String cellValue,int width){
super(cellValue,CellTypeEnum.LABEL);
this.width = width;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
以及枚举类型:CellTypeEnum
package com.work.gongchenglion.unity;
public enum CellTypeEnum {
STRING //字符
,DIGIT //数字
,LABEL //标签
}
3、将自定义的结构填充数据,显示出来。
最后的表格类:CustomeTableItem,这里开始直接开始涉及部分UI。与Adapter有交叉。
这里适配器内添加数据的方法,在表格类里实现,方便下直接使用表格类的变量。
package com.work.gongchenglion.unity;
/*
* To Object
* 数据存储的组织方式
*/
import java.util.ArrayList;
import com.work.gongchenglion.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.TextView;
public class CustomeTableItem extends LinearLayout {
private Context context = null;
private boolean isRead = false;//是否只读
private ArrayList<View> viewList = new ArrayList<View>();//行的表格列表
private int[] headWidthArr = null;//表头的列宽设置
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,ArrayList<ItemCell> itemCells
,int[] headWidthArr,boolean isRead){
this.setOrientation(LinearLayout.VERTICAL);//第一层布局垂直,LinearLayout父类的方法
this.context = context;
this.headWidthArr =headWidthArr.clone();
this.addCell(itemCells);
}
//
private void addCell(ArrayList<ItemCell> itemCells){
this.removeAllViews();
LinearLayout secondLayout = new LinearLayout(context);
secondLayout.setOrientation(LinearLayout.HORIZONTAL);
secondLayout.setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
this.addView(secondLayout);
int cellIndex = 0;
for(int i=0;i<itemCells.size();i++){//遍历itemCells内的所有Cell
ItemCell itemCell = itemCells.get(i);
int endIndex = cellIndex + 1;//所占列数
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(android.view.ViewGroup.LayoutParams.WRAP_CONTENT,android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
secondLayout.addView(v_line);
}
}
}
public void refreshData(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 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 View getLabelView(){
return LayoutInflater.from(context).inflate(R.layout.atom_text_view, null);
}
private View getInputView(){
return 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){//非只读
}
}
}
适配器类:重点当然是getView()方法。
package com.work.gongchenglion.unity;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import com.work.gongchenglion.R;
public class CustomeTableViewAdapter extends BaseAdapter{
private Context context;
private LayoutInflater inflater;
private ArrayList<HashMap<String,Object>> lists;
private ListView listView = null;
private boolean isReadOnly = false;
private int[] arrHeadWidth = null;
public CustomeTableViewAdapter(Context context, ArrayList<HashMap<String,Object>> lists
,ListView listView,boolean isReadOnly
,int[] arrHeadWidth) {
super();
this.context = context;
this.lists = lists;
inflater = LayoutInflater.from(context);
this.listView = listView;
this.isReadOnly = isReadOnly;
this.arrHeadWidth = arrHeadWidth;
this.listView.setAdapter(this);
}
@Override
public int getCount() {
return lists.size();
}
@Override
public Object getItem(int arg0) {
return arg0;
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(int index, View view, ViewGroup arg2) {
HashMap<String, Object> map = lists.get(index);
String type = (String)map.get("rowtype");
ArrayList<ItemCell> itemCells = new ArrayList<ItemCell>();
for(int i=0;i<map.size()-1;i++){
ItemCell itemCell = (ItemCell)map.get(i+"");
itemCells.add(itemCell);
}
//getTag 获得View绑定的Object,这里是一个CustomeTableItem的对象
if(view == null){
view = inflater.inflate(R.layout.customel_list_item, null);//获取自定义View
CustomeTableItem itemCustom = (CustomeTableItem)view.findViewById(R.id.custome_item);
//向自定义View添加数据,添加显示
itemCustom.buildItem(context,itemCells,arrHeadWidth,isReadOnly);
view.setTag(itemCustom);
}else{
CustomeTableItem itemCustom = (CustomeTableItem)view.getTag();
itemCustom.refreshData(itemCells);
}
if(index%2 == 0){
view.setBackgroundColor(Color.argb(250 , 255 , 255 , 255 ));
}else{
view.setBackgroundColor(Color.argb(250 , 224 , 243 , 250 ));
}
return view;
}
}
谢谢,以上纯粹个人理解。