这是两年之前写的技术博客,思路还是有可以借鉴的地方,就贴过来保存一下
由于就职公司业务需求,要实现在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>
最后的显示效果为:
本文完,如有更好实现方法或疑问请提出,共同学习,感谢!
网友评论