【Android 个人理解(五) 】适配器的设计思维

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;
    }

}

谢谢,以上纯粹个人理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值