I have 4 different types of rows that have each their own xml layout. How do i manage them?

I keep on getting only the first row type and never the other ones. and then Im imagining i'll also have to handle the recycling. but i dont know how. I put down some code, but im deffinitly missing something. thanks

here is the code:

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context _context;
    private List<String> _listDataHeader; // header titles

    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;


    public ExpandableListAdapter(Context context, List<String> listDataHeader,
            HashMap<String, List<String>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
    }

    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    }

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

    @Override
    public int getChildTypeCount() {
        // TODO Auto-generated method stub
        Log.i("getChildTypeCount()", "getChildTypeCount()");
        return (4);
    }

    @Override
    public int getGroupTypeCount() {
        // TODO Auto-generated method stub
        return super.getGroupTypeCount();
    }

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

        String childText = (String) getChild(groupPosition, childPosition);
        int itemType = getChildType(groupPosition,childPosition);   

        DescrizioneViewHolder descrizioneViewHolder = new DescrizioneViewHolder();
        DistanzaViewHolder distanzaViewHolder = new DistanzaViewHolder();
        CategoriaViewHolder categoriaViewHolder = new CategoriaViewHolder();
        OrdinaViewHolder ordinaViewHolder = new OrdinaViewHolder();

        Log.i("groupPosition", Integer.toString(groupPosition));
        Log.i("childPosition", Integer.toString(childPosition));
        Log.i("itemType", Integer.toString(itemType));
        Log.i("----", "----");


        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);


             switch (itemType) {
                 case 0:
                     convertView = inflater.inflate(R.layout.listview_item_filter_descrizione, null);
                     descrizioneViewHolder.etDescrizione = (EditText) convertView.findViewById(R.id.etDescrizione);
                     break;
                 case 1:
                     convertView = inflater.inflate(R.layout.listview_item_filter_distanza, null);
                     distanzaViewHolder.etIndirizzo = (EditText) convertView.findViewById(R.id.etIndirizzo);
                     distanzaViewHolder.btnCercaIndirizzo = (Button) convertView.findViewById(R.id.btnCercaIndirizzo);
                     distanzaViewHolder.tvRaggioAzione = (TextView) convertView.findViewById(R.id.tvRaggioAzione);
                     distanzaViewHolder.radioGroup1 = (RadioGroup) convertView.findViewById(R.id.radioGroup1);
                     break;
                 case 2:
                     convertView = inflater.inflate(R.layout.list_item_filter, null);
                     categoriaViewHolder.tvCategoria = (TextView) convertView.findViewById(R.id.lblListItem);
                     categoriaViewHolder.tvCategoria.setText(childText);
                     break;
                 case 3:
                     convertView = inflater.inflate(R.layout.listview_item_filter_ordina, null);
                     ordinaViewHolder.tvOrdina = (TextView) convertView.findViewById(R.id.tvOrdina);
                     ordinaViewHolder.btnDecrescente = (Button) convertView.findViewById(R.id.btnDecrescente);
                     ordinaViewHolder.btnCrescente = (Button) convertView.findViewById(R.id.btnCrescente);
                     ordinaViewHolder.tvOrdina.setText(childText);
                     break;
            }
        }
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
    }

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

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

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

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

        TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setTextSize(25);
        lblListHeader.setText(headerTitle);

        return convertView;
    }

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

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

    public static class DescrizioneViewHolder {
        public EditText etDescrizione;
    }

    public static class DistanzaViewHolder {
        public EditText etIndirizzo;
        public Button btnCercaIndirizzo;
        public TextView tvRaggioAzione;
        public RadioGroup radioGroup1;
    }

    public static class CategoriaViewHolder {
        public TextView tvCategoria;
    }

    public static class OrdinaViewHolder {
        public TextView tvOrdina;
        public Button btnDecrescente;
        public Button btnCrescente ;
    }
}
有帮助吗?

解决方案

I don't see any association between the ViewHolder respectivly the classes you use for it and the convertView itself, which means the ViewHolder doesn't get attached to the ViewGroup. E.g.

LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

    if (convertView == null) {
        convertView = mInflater.inflate(getLayoutResourceId(), null);
        holder = new ViewHolder();
        convertView.setTag(holder);
    }
    else {
        holder = (ViewHolder) convertView.getTag();
    }

And remember to set the values also when the convertView is not null. The calls to getChildView are subsequently repeated for all itmes in your list. Example continued:

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

    String childText = (String) getChild(groupPosition, childPosition);
    int itemType = getChildType(groupPosition,childPosition);   

    switch (itemType) {
    case 0:
        return getChildViewDistanza(groupPosition, childPosition, isLastChild, convertView, parent);
        break;
    case 1:
       ....
        }

    return convertView;
}

 public View getChildViewDistanza(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
     DistanzaViewHolder distanzaViewHolder;

     if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.listview_item_filter_descrizione, null);
        DistanzaViewHolder distanzaViewHolder = new DistanzaViewHolder();
        convertView.setTag(distanzaViewHolder);
     }
     else {
        distanzaViewHolder = convertView.getTag();
     }
     descrizioneViewHolder.etDescrizione = (EditText) convertView.findViewById(R.id.etDescrizione);

     return convertView;
 }

if you would like to get rid of the repetative element concerning layout - inflating and setting the tag, you could easily write a method for this, too, if you use a common base class amongs your ViewHolder:

 protected View inflateLayoutAndSetTag(int resourceID, BaseViewHolder holder) {
     LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View convertView = inflater.inflate(resourceID) , null);
     convertView.setTag(holder) );

     return convertView;
 }

and call it as:

if (convertView == null) {
    DistanzaViewHolder distanzaViewHolder = new DistanzaViewHolder();
    convertView = inflateLayoutAndSetTag(R.layout.listview_item_filter_descrizione, distanzaViewHolder);
 }

actually you can even do things such as

 protected <TViewHolder> Pair<View, TViewHolder> getViewHolderAndConvertView(View convertView, int resourceID, TViewHolder dummy) { /** TViewHolder is a type - parameter that is actually unused, just needed for the instanziation of the right type and the pair - type ***/
 if (convertView == null) {
    LayoutInflater inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(resourceID, null);
    TViewHolder viewHolder = TViewHolder.class.newInstance();
    convertView.setTag(viewHolder);
 }
 else {
    viewHolder = convertView.getTag();
 }

 return new Pair<View, TViewHolder>(convertView, viewHolder);

}

and call this as e.g.:

 Pair<View, DistanzaViewHolder> pair = getViewHolderAndConvertView(convertView, R.layout.listview_item_filter_descrizione, (DistanzaViewHolder) null);
DistanzaViewHolder viewHolder = pair.second;
convertView = pair.first;

removing all of that repetativ code. But's that's a little bit out of scope of this question. ;)

其他提示

You are missing an implementation of getChildType(). You will have to implement this in order to determine which child is of which type.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top