有时候系统提供的组件并不能提供某些特定的功能,需要我们自己去实现,就比如最近项目中遇到的一个产品属性要实现同一组下的只能单选,而组间的要求可以是多选的,这时系统给我们提供的ExpandableListView就无法满足我们的需求了,需要我们自己去写一些业务逻辑去提供这个功能,下面是功能的效果图
这是未选择时的效果图,下面是选中时的效果图:
这样就实现了我们要的功能...
主要代码如下:
1.Adapter主要代码
public class PropertySiftExpandListAdapter extends BaseExpandableListAdapter
{
private Context context;
private ArrayList dataList;
private ViewHolder childHolder;
private ViewHolder groupHolder;
private Options child;
private SearchProperty group;
private GetPropertyListener propertyListener;
public HashMap recordOptions; //哈希表来维护被选中的属性
public PropertySiftExpandListAdapter(Context context, ArrayList dataList,
GetPropertyListener propertyListener)
{
this.context = context;
this.dataList = dataList;
this.propertyListener = propertyListener;
this.recordOptions = new HashMap();
}
@Override
public Object getChild(int groupPosition, int childPosition)
{
return dataList.get(groupPosition).options.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition)
{
return dataList.get(groupPosition).options.size();
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.from(context).inflate(R.layout.property_child_item, null);
childHolder = new ViewHolder();
childHolder.groupName = (TextView) convertView.findViewById(R.id.property_name);
childHolder.checkBox = (CheckBox) convertView.findViewById(R.id.property_box);
childHolder.propertyLayout = (RelativeLayout) convertView.findViewById(R.id.search_sift_property);
convertView.setTag(childHolder);
}
else
{
childHolder = (ViewHolder) convertView.getTag();
}
childHolder.checkBox.setChecked(false);
child = (Options) getChild(groupPosition, childPosition);
childHolder.groupName.setText(child.name);
childHolder.propertyLayout.setId(getID(groupPosition, childPosition).realId);
childHolder.propertyLayout.setTag(R.id.property_one, child);
childHolder.propertyLayout.setTag(R.id.property_two, getID(groupPosition, childPosition));
//如果哈希表不为空
if (recordOptions.size() != 0)
{
RecordGroup temp = recordOptions.get(groupPosition);
if (temp != null)
{
//将表中存在的属性节点置为选中状态
if (temp.childId == childPosition)
{
childHolder.checkBox.setChecked(true);
}
}
}
return convertView;
}
@Override
public Object getGroup(int groupPosition)
{
return dataList.get(groupPosition);
}
@Override
public int getGroupCount()
{
return dataList.size();
}
@Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
group = (SearchProperty) getGroup(groupPosition);
if (convertView == null)
{
convertView = LayoutInflater.from(context).inflate(R.layout.property_group_item, null);
groupHolder = new ViewHolder();
groupHolder.groupName = (TextView) convertView.findViewById(R.id.property_name);
groupHolder.checkBox = (CheckBox) convertView.findViewById(R.id.property_box);
convertView.setTag(groupHolder);
}
else
{
groupHolder = (ViewHolder) convertView.getTag();
}
if (group.choosen.equals("true"))
{
groupHolder.checkBox.setVisibility(View.VISIBLE);
}
else
{
groupHolder.checkBox.setVisibility(View.INVISIBLE);
}
groupHolder.groupName.setText(group.name);
return convertView;
}
class ViewHolder
{
TextView groupName;
CheckBox checkBox;
RelativeLayout propertyLayout;
}
@Override
public boolean hasStableIds()
{
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return true;
}
public RecordGroup getID(int groupPosition, int childPosition)
{
String id = String.valueOf(groupPosition) + String.valueOf(childPosition);
return new RecordGroup(id, groupPosition, childPosition);
}
public interface GetPropertyListener
{
public void getPropertyData(int groupId, Options property);
}
/**
* 此处根据点击的不同,利用HashMap将选中的数据保存起来,以便跟新为选中状态
*
public void changeStyle(RecordGroup record, Options options)
{
// 判断是否已经存在此组ID
if (recordOptions.containsKey(record.groupId))
{
// 取出此组ID
RecordGroup tempRecord = recordOptions.get(record.groupId);
if (tempRecord.childId != record.childId)
{
recordOptions.put(tempRecord.groupId, record);
propertyListener.getPropertyData(tempRecord.groupId, options);
}
else
{
recordOptions.remove(record.groupId);
propertyListener.getPropertyData(tempRecord.groupId, null);
}
}
else
{
recordOptions.put(record.groupId, record);
propertyListener.getPropertyData(record.groupId, options);
}
notifyDataSetChanged();
}
}
自定义一个实体类,用来区分不同的选项。
public class RecordGroup
{
public int realId;
public int groupId;
public int childId;
public RecordGroup(String realId, int groupId, int childId)
{
this.realId = Integer.parseInt(realId);
this.groupId = groupId;
this.childId = childId;
}
}
以上就是我们实现此功能的主要代码。
思路:
将点击的不同选项用HashMap保存起来,存入Map时,先判断是否有相同的组ID,没有则直接添加,有则跟新为最新的组ID。存子项时,思路与存组时的思路是一致的。
第一次写博客,如有写的不好的地方请指出,代码有不懂的可以向我要源码,谢谢大家。