美文网首页android技术专栏Android开发程序员
Adapter+ListView进阶——巧妙实现装配式界面

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

作者: 9efe1db2c646 | 来源:发表于2017-10-09 10:53 被阅读153次

这是两年之前写的技术博客,思路还是有可以借鉴的地方,就贴过来保存一下

由于就职公司业务需求,要实现在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>

最后的显示效果为:


这里写图片描述

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

相关文章

网友评论

    本文标题:Adapter+ListView进阶——巧妙实现装配式界面

    本文链接:https://www.haomeiwen.com/subject/mavuyxtx.html