如何用两个不同的对象填充 ExpandableListView

How do you populate a ExpandableListView with two different Objects

我有一个可扩展列表视图,想用两个不同的对象填充它,目前我只是用 Tareas 对象填充子项,但想用不同的对象 (Metas) 填充同一个子项列表。我怎样才能做到这一点,因为我的适配器只是用 Tareas 对象填充列表,而不是接受 Metas 对象。

UPDATE

这是我的 ExpandableListViewAdapter:

public class CalendarioAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<String> mCalendarioListHeader;
private HashMap<String, List<Object>> mCalendarioListChild;
private static final int CHILD_TYPE_META = 0;
private static final int CHILD_TYPE_PLANES = 1;


public CalendarioAdapter(Context context, List<String> listDataHeader,
                         HashMap<String, List<Object>> listChildData) {
    this.mContext= context;
    this.mCalendarioListHeader= listDataHeader;
    this.mCalendarioListChild = listChildData;
}
@Override
public int getChildTypeCount() {
    return 2;
}


@Override
public int getGroupCount() {
    return this.mCalendarioListHeader.size();
}

@Override
public int getChildrenCount(int groupPosition) {
    List childList = mCalendarioListChild.get(mCalendarioListHeader.get(groupPosition));
    if (childList != null && ! childList.isEmpty()) {
        return childList.size();
    }
    return 0;
}


@Override
public Object getGroup(int groupPosition) {
    return this.mCalendarioListHeader.get(groupPosition);
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    return this.mCalendarioListChild.get(this.mCalendarioListHeader.get(groupPosition))
            .get(childPosition);
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public boolean hasStableIds() {
    return false;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    String headerTitle = (String) getGroup(groupPosition);
    String listSize = getChildrenCount(groupPosition) +"";
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this.mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.calendario_list_header, null);
    }

    TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.lblListHeader);
    TextView sizeOfList = (TextView) convertView.findViewById(R.id.calendarioListSize);
    sizeOfList.setText(listSize);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(headerTitle);

    return convertView;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {


    Integer childType = (getChildType(groupPosition, childPosition));
    Log.d("childType", childType+"");

    LayoutInflater layoutInflater = (LayoutInflater) this.mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null|| convertView.getTag() != childType) {

        switch (childType) {

            case CHILD_TYPE_META:
                convertView = layoutInflater.inflate(R.layout.metas_list_row, null);
                convertView.setTag(childType);
                break;
            case CHILD_TYPE_PLANES:
                convertView =  layoutInflater.inflate(R.layout.calendario_list_row, null);
                convertView.setTag(childType);
                break;
            default:

                break;
        }
    }
    switch (childType) {
        case CHILD_TYPE_META:
            Metas metas = (Metas) getChild(groupPosition, childPosition);
            TextView txtMetasChild =  convertView.findViewById(R.id.metasTxtChild);
            TextView fechaMetasChild = convertView.findViewById(R.id.fechaMetaChild);
            txtMetasChild.setText(metas.getMeta());
            fechaMetasChild.setText(metas.getFecha());
            break;
        case CHILD_TYPE_PLANES:
            Tareas tareas = (Tareas) getChild(groupPosition, childPosition);
            TextView txtDescripcionChild = (TextView) convertView
                    .findViewById(R.id.descripcionTareaText);
            TextView txtListaChild = (TextView) convertView
                    .findViewById(R.id.listaTareaText);
            txtDescripcionChild.setText(tareas.getDescripcion());
            txtListaChild.setText(tareas.getLista());
            break;

        default:
            break;
    }

    return convertView;


  }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    @Override
    public int getChildType(int groupPosition, int childPosition) {
        Object child = getChild(groupPosition, childPosition);
        Log.d("ChildType", child+"");
        if(child instanceof Metas){
            return CHILD_TYPE_META;
        } else if(child instanceof Tareas) {
            return CHILD_TYPE_PLANES;
        }
        else{
// should never happen, so do error handling here
            throw new RuntimeException("only classes Metas and Tareas permitted");
        }
    }
}

And on my Fragment I populate the list like this:

       private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<Object>>();

        // Adding header data
        listDataHeader.add(diasText[0]);
        listDataHeader.add(diasText[1]);
        listDataHeader.add(diasText[2]);
        listDataHeader.add(diasText[3]);
        listDataHeader.add(diasText[4]);
        listDataHeader.add(diasText[5]);
        listDataHeader.add(diasText[6]);

        // Adding child data

        listDataChild.put(listDataHeader.get(0), dia1List);
        listDataChild.put(listDataHeader.get(1), dia2List);
        listDataChild.put(listDataHeader.get(2), dia3List);
        listDataChild.put(listDataHeader.get(3), dia4List);
        listDataChild.put(listDataHeader.get(4), dia5List);
        listDataChild.put(listDataHeader.get(5), dia6List);
        listDataChild.put(listDataHeader.get(6), dia7List);
    }

任何关于如何实现我的要求的想法将不胜感激!

子类化 BaseExpandableListAdapter 时,您可以为组项和子项提供不同的 View 类型。我只会概述如何做不同的子 View 类型,因为那是你想要做的(而且 post 会变得足够长)。

View 类型由 int 值表示,例如

private static final int TYPE_TAREAS = 0;
private static final int TYPE_METAS = 2;

因此,在您的情况下,您传入 HashMap<String, List<Object>> 而不是 HashMap<String, List<Tareas>> 并将 getChildTypeCount() 覆盖为 return 2(不同视图类型的数量)。 (当然你也可以使用 TareasMetas 的任何共同祖先来代替 Object

然后您将 getChildType (int groupPosition, int childPosition) 覆盖为 return 正确的 int 值(TYPE_TAREAS 或 TYPE_METAS),用于 View 类型具体条目。要确定类型,请在 List 条目上使用 instanceof

最后,当覆盖 getChildView() 时,您对 List 条目执行必要的类型转换,并通过调用 getChildType() 确定 View 类型。与 ListView 一样,您可以重复使用 convertView.

以下是 documentation for getChildView() 对这个话题的看法:

convertView View: the old view to reuse, if possible. You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. It is not guaranteed that the convertView will have been previously created by getChildView(int, int, boolean, View, ViewGroup).

如果 convertView 无法重复使用,您根据 View 类型创建一个新的 View,方法是膨胀所需的布局。 遵循 ViewHolder 模式是个好主意。您可能需要两个完全不同的 ViewHolder 或一个从另一个扩展,这取决于您的两个数据之间的差异 类.

其余一切照常:-)