Search code examples
androidexpandablelistviewchildviews

ExpandableListView reorganizes children views order on every group expand


In my ExpandableListView, I want to have a first child of every group to be different xml view than other children in the group.

What I want to achieve would be something like this:

enter image description here

I manage to do that with the following code:

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View newView, ViewGroup parent) {



    if (newView==null){

        // CHILD HEADER
        if (childPosition == 0){
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            newView = infalInflater.inflate(R.layout.super_trener_cell_child_header, null);


        // CHILD CELL
        else{
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            newView = infalInflater.inflate(R.layout.super_trener_cell_child, null);
            }
    }

    return newView;
}

And that works just fine. THere is one problem however..whenever I expand and shrink the cell, I get another order of appearence of the child cells.

Here are some screenshots, showing what's going on (Numbers are representing the order in which they should appear):

enter image description here enter image description here

What could be the cause of this cell inversion, after each click on the group header?

EDIT: Entire Adapter Code:

public class SuperTrenerCellAdapter extends BaseExpandableListAdapter {

Context context;
List<SuperTrenerTopic> topics = new LinkedList<SuperTrenerTopic>();
private static LayoutInflater inflater = null;

public SuperTrenerCellAdapter(List<SuperTrenerTopic> topics, Context context) {
    this.topics = topics;
    this.context = context;
}

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

@Override
public int getChildrenCount(int groupPosition) {
    SuperTrenerTopic topic = topics.get(groupPosition);
    return topic.getLessonList().size()+1;
}

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

@Override
public Object getChild(int groupPosition, int childPosition) {
    return 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) {
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.super_trener_cell_header, null);
    }
    SuperTrenerTopic topic = topics.get(groupPosition);
    TextView topicTitle = (TextView)convertView.findViewById(R.id.stc_topicName);
    topicTitle.setText(topic.getName());

    return convertView;
}

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

    SuperTrenerTopic topic = topics.get(groupPosition);
    if (convertView==null){

        // CHILD HEADER
        if (childPosition == 0){
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.super_trener_cell_child_header, null);


        }

        // LESSON CELL
        else{
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.super_trener_cell_child, null);
            SuperTrenerLesson stl = topic.getLessonList().get(childPosition-1);
            TextView title = (TextView)convertView.findViewById(R.id.st_cell_child_title);

            title.setText(""+stl.getTitle());

        }
    }

    return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    if (childPosition == 0){
        return false;
    }
    else{
        return true;
    }
}

}


Solution

  • the problem is your convertView in getChildView. comment out for a minute convertView null check so you can see whats happening.

    make it look like this:

        @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
        SuperTrenerTopic topic = topics.get(groupPosition);
        //if (convertView==null)
    {
    
            // CHILD HEADER
            if (childPosition == 0){
                LayoutInflater infalInflater = (LayoutInflater) this.context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = infalInflater.inflate(R.layout.super_trener_cell_child_header, null);
    
    
            }
    
            // LESSON CELL
            else{
                LayoutInflater infalInflater = (LayoutInflater) this.context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = infalInflater.inflate(R.layout.super_trener_cell_child, null);
                SuperTrenerLesson stl = topic.getLessonList().get(childPosition-1);
                TextView title = (TextView)convertView.findViewById(R.id.st_cell_child_title);
    
                title.setText(""+stl.getTitle());
    
            }
        }
    
        return convertView;
    }
    

    When you open and close the headers its recycling the views so convertView might not come back as null and its therefore using the old data that was stored. Your not setting anything new with the recycled view (convertView). You need to change your conditions to accomodate when the childViews are actually recycled (that is when convertView wont be null).