Adapter+ListView进阶——巧妙实现装配式界面

来源:互联网 发布:映客怎么上淘宝的链接 编辑:程序博客网 时间:2024/05/01 11:03
由于就职公司业务需求,要实现在Android移动端录入大量复杂表格,然后上传到后台分析计算,复杂程度大致如下:

表格内容一

表格内容二
难点不在于表格的复杂,而在于每种表格都不一致,这就导致无法通过绘制统一模板实现表格数据的录入。
通过观察,每种表格虽然多变,但总体只有几种类型,那么是否能否通过将表格抽象成多层嵌套的类,然后在类中设置描述表格类型的参数,最后根据参数生成对应的表格?
于是用xMind6画出了数据结构图:
这里写图片描述
然后开始按图动手写代码,分别创建了各级类及相应的listView、adapter,此处不赘述。装配式界面实现的关键在于最后一级的Adapter的getView(),以下为代码:

//由于需要按顺序读取、使用,所以ViewHolder内部使用List<View>来装View    private class ViewHolder {        List<View> viewsList;    }// 本方法适用于装配式表格控件,本adapter主要思路请看注释    @Override    public View getView(final int position, View convertView, ViewGroup parent) {        // 初始化holder        holder = new ViewHolder();        holder.viewsList = new ArrayList<View>();        //注意:所有传入匿名内部类onClick()的变量均应为final        final TableOthersRowItem rowItem = dataRows.get(position);        columnList = rowItem.getColumnList();        // 如果convertView为空则初始化convertView        if (convertView == null) {            convertView = new LinearLayout(context);// 初始化,避免空指针,此处如有需要可通过LayoutParams设置初始化属性            // 生成装配式item的四个步骤 :            // 1.创建备用素材布局[tempLayout];            // 2.获取该次循环所用到的控件/子布局[tempView];            // 3.从[tempLayout]中移除[tempView],然后添加[tempView]到[convertView]及[holder.viewList];            // 4.从[convertView]获取holder,并自定义控件内容;            for (int i = 0; i < columnList.size(); i++) {                String type = tableTypeList.get(i);                LinearLayout tempLayout = (LinearLayout) inflater.inflate(                        R.layout.list_item_rowdata_others, parent, false);                View tempView = new View(context);                switch (type) {                case "C":                    tempView = tempLayout.findViewById(R.id.photo_layout);                    break;                case "T":                case "PT":                case "AS":                    tempView = tempLayout.findViewById(R.id.others_t);                    break;                case "S":                    tempView = tempLayout.findViewById(R.id.others_s);                case "ET":                    tempView = tempLayout.findViewById(R.id.others_et);                    break;                default:                    tempView = tempLayout.findViewById(R.id.others_t);                    break;                }                tempLayout.removeAllViews();//由于各个控件的宽度不同,所以这里要根据控件类型设置weight,确保控件间比例正确,代码将在后面贴出                tempView.setLayoutParams(Utils.setViewWeight(type));                ((ViewGroup) convertView).addView(tempView);                holder.viewsList.add(tempView);            }            int height = Utils.dip2px(context, 70);            convertView                    .setLayoutParams(new android.widget.AbsListView.LayoutParams(                            LayoutParams.MATCH_PARENT, height));            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        //设置每行Item的点击事件,此处也要注意控件应为final,确保每个点击事件独立处理。        for (int i = 0; i < columnList.size(); i++) {            final String contentString = columnList.get(i);            String type = tableTypeList.get(i);            switch (type) {            case "C":                View tempView = convertView.findViewById(R.id.photo_layout);                final ImageView iv_photo_add = (ImageView) tempView                        .findViewById(R.id.iv_photo_add);                final ImageView iv_photo_local = (ImageView) tempView                        .findViewById(R.id.iv_photo_local);                final ImageView iv_photo = (ImageView) tempView                        .findViewById(R.id.iv_photo);                iv_photo_add.setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View arg0) {                        lister.onGetPhoto(dataRows.get(position), false);                    }                });                iv_photo_local.setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View arg0) {                        lister.onGetPhoto(dataRows.get(position), true);                    }                });                iv_photo.setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View arg0) {                        lister.onPhotoClicked(dataRows.get(position), 0);                    }                });                int size = rowItem.getPhotoList().size();                if (size > 0) {                    new LoadImageFileTask(iv_photo, rowItem.getPhotoList()                            .get(0).getPath(), false).execute();                }                break;            case "T":            case "PT":                ((TextView) holder.viewsList.get(i)).setText(contentString);                final TextView aTextView = (TextView) holder.viewsList.get(i);                aTextView.setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View arg0) {                        lister.onPTClicked(aTextView);                    }                });                break;            case "PS":                ((TextView) holder.viewsList.get(i)).setText(rowItem.getScoreValue());                final TextView bTextView = (TextView) holder.viewsList.get(i);                bTextView.setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View arg0) {                        lister.onRulesClicked(rowItem);                    }                });                break;            default:                ((TextView) holder.viewsList.get(i)).setText(contentString);                break;            }        }        return convertView;    }    private class ViewHolder {        List<View> viewsList;    }

以下为设置weight的setViewWeight()方法:

    public static LayoutParams setViewWeight(String type) {        android.widget.LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(                LayoutParams.WRAP_CONTENT,                LayoutParams.MATCH_PARENT, 1.0f);           param.gravity=Gravity.CENTER;        param.width=0;        switch (type) {        case "PT"://点击显示文本        case "S"://分数(可填写)        case "PS"://点击选择分数(可填写)        case "FS"://满分        case "DS"://得分        case "AS"://得分            param.weight=0.5f;            break;        case "T"://文本        case "ET"://可编辑文本            param.weight=1.0f;            break;        case "C"://相机            param.weight=1.0f;            break;        case "LT"://长文本            param.weight=2.0f;            break;        default:            break;        }

以下为adapter中所使用到的素材布局tempLayout:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/item_others_material"    android:layout_width="match_parent"    android:layout_height="74.1dp"    android:background="#f7f7f7"    android:gravity="center_vertical"    android:orientation="horizontal" >    <TextView        android:id="@+id/others_t"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1"        android:background="@drawable/bg_table_select"        android:gravity="center"        android:text="文本"        android:textColor="#006faf" />    <EditText        android:id="@+id/others_et"        android:layout_width="0dp"        android:layout_height="40dp"        android:layout_weight="1"        android:background="@drawable/bg_table_select"        android:gravity="center"        android:imeOptions="actionNext"        android:inputType="numberDecimal|text"        android:maxLength="4"        android:singleLine="true"        android:text="可编辑文本"        android:textColor="#006faf"        android:textSize="16sp" />    <EditText        android:id="@+id/others_s"        android:layout_width="0dp"        android:layout_height="40dp"        android:layout_weight="1"        android:background="@drawable/bg_table_select_design"        android:digits="0123456789.-"        android:gravity="center"        android:imeOptions="actionNext"        android:inputType="numberDecimal|text"        android:maxLength="4"        android:singleLine="true"        android:text="得分"        android:textColor="#006faf"        android:textSize="16sp" />    <LinearLayout        android:id="@+id/photo_layout"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="2"        android:background="@drawable/bg_table_select"        android:clickable="true"        android:gravity="center"        android:orientation="horizontal"        android:padding="3.2dp" >            <ImageView                android:id="@+id/iv_photo"                android:layout_width="42dp"                android:layout_height="42dp"                android:background="@drawable/bg_edit_text"                android:gravity="center" />            <ImageView                android:id="@+id/iv_photo_local"                android:layout_width="42dp"                android:layout_height="42dp"                android:gravity="center"                android:src="@drawable/pictures_alt" />            <ImageView                android:id="@+id/iv_photo_add"                android:layout_width="42dp"                android:layout_height="42dp"                android:gravity="center"                android:src="@drawable/camera" />    </LinearLayout></LinearLayout>

最后的显示效果为:
这里写图片描述

本文完,如有更好实现方法或疑问请提出,共同学习,感谢!

另外本人在找工作,希望在广州,Android,简历csdn可直接看到。

2015.6.19

0 0