简体   繁体   中英

How to handle recycling in Expandablelistview with different child layouts?

As we all know Android's listview and expandablelistview recycles its view. More info: The nuance of android listview .

I've read articles and information such as the above link on how to handle that but they only give only examples on list views not on Expandablelistview (whereas getView is the only method in listview while in expandablelistview there is getGroupView and getChildView).

My expandable listview's children has or needs to have different layouts because that's necessary to achieve the application's output.

Now, my question is how to properly handle the recycling of expandable list view that inflates different layouts in its child? Such as where to put the viewHolder or convertView in my expandablelistview's getChildView method.

I followed the code below from this site in achieving a child that inflates different layouts according to its position.

Whenever I click on another group. The previous group's child recycles its view to its default thus spinner and edit text values is not being retained. I think maybe its because it inflates once again the view?

Below is my getChildView method:

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

            //layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
            //convertView = layoutInflater.inflate(R.layout.expandable_child_layout, parent, false);
        try{
            int itemType = getChildType(groupPosition, childPosition);

            switch(itemType){
            case 0:
                ViewHolder mainHolder = null;
                View v1 = null;
                if(v1 == null){

                    mainHolder = new ViewHolder();
                    v1 = View.inflate(context, R.layout.newtrip_main, null);
                    v1.setTag(mainHolder);

                    mainHolder.tripType = (Spinner) v1.findViewById(R.id.spinTripType);

                    /*TripTypeAdapter = new ArrayAdapter<String>(NewTrip.this, android.R.layout.simple_spinner_item,getResources().getStringArray(R.array.triptypes)); //selected item will look like a spinner set from XML
                    TripTypeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    tripType.setAdapter(TripTypeAdapter);*/
                    mainHolder.tripType.setOnItemSelectedListener(this);

                }//else{
                    //mainHolder = (ViewHolder) v1.getTag();
                //}
                return v1;
                //break;
            case 1:

                ViewHolder  budgetHolder = null;
                View v2 = null;
                if(v2 == null){

                    budgetHolder = new ViewHolder();
                    v2 = View.inflate(context, R.layout.newtrip_budget, null);
                    v2.setTag(budgetHolder);

                    budgetHolder.budget = (Spinner) v2.findViewById(R.id.spinBudget);
                    budgetHolder.budgetAdapter = new ArrayAdapter<String>(NewTrip.this, android.R.layout.simple_spinner_item,getResources().getStringArray(R.array.budgettype)); //selected item will look like a spinner set from XML
                    budgetHolder.budgetAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    budgetHolder.budget.setAdapter(budgetHolder.budgetAdapter);
                    budgetHolder.budget.setOnItemSelectedListener(this);

                }

                return v2;
                //break;
            case 2:

                ViewHolder  foodHolder= null;
                View v3 = null;
                if(v3 == null){
                    foodHolder = new ViewHolder();
                    v3 = View.inflate(context, R.layout.newtrip_food, null);
                    v3.setTag(foodHolder);
                }
                return v3;
                //break;
            case 3:

                ViewHolder  accomHolder= null;
                View v4 = null;
                if(v4 == null){
                    accomHolder = new ViewHolder();
                    v4 = View.inflate(context, R.layout.newtrip_accommodation, null);
                    v4.setTag(accomHolder);

                    accomHolder.accommodation = (Spinner) v4.findViewById(R.id.spinAccommodation);

                    accomHolder.accommodationAdapter = new ArrayAdapter<String>(NewTrip.this, android.R.layout.simple_spinner_item,getResources().getStringArray(R.array.economicalAccomodation)); //selected item will look like a spinner set from XML
                    accomHolder.accommodationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    accomHolder.accommodation.setAdapter(accomHolder.accommodationAdapter);
                    //return convertView;
                }

                return v4;
                //break;

            }
        }catch(Exception e){
            Toast toast = Toast.makeText(context, e.toString(), Toast.LENGTH_LONG);
            toast.show();
        }
            convertView.invalidate();
            return convertView;
    }

and here's the getGroupView method:

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {          


        convertView = View.inflate(context, R.layout.expandable_group_layout, null);
        TextView txtView = (TextView) convertView.findViewById(R.id.txt1);                 

        if(groupPosition == 0) {
          txtView.setText("   MAIN");
          txtView.setTextSize(15f);
          }
        if(groupPosition == 1) {
            txtView.setText("   BUDGET");
            txtView.setTextSize(15f);
          }
        if(groupPosition == 2) {
            txtView.setText("   FOOD");
            txtView.setTextSize(15f);
          }
        if(groupPosition == 3) {
            txtView.setText("   ACCOMMODATION");
            txtView.setTextSize(15f);
          }

        convertView.invalidate();
        return convertView;

    }

It's exactly the same thing. Just treat the getChildView method the same way you would as the normal getView . So for your case, you'd want to do the following:

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

@Override
public int getChildTypeCount() {
    return getGroupCount();
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    switch (getChildType(groupPosition, childPosition) {
    case 1:
        ViewHolder vh = null;
        if (convertView == null) {
            vh = new ViewHolder();
            //Inflate your view
            convertView.setTag(vh);
        } else {
            vh = (ViewHolder) convertView.getTag();
        }
        //Load any data into view
        return convertView;
    case 2:
        //Repeat for all expected types
    }
}

要控制可扩展列表视图中子列表的回收,请确保将更改后的数据保存在哈希图中,以便在向上滚动时可以跟踪更改后的数据,或者不使用列表和列表来解析哈希图数据。您可以看到结果。

I had almost the same problem, I solve it with this : https://stackoverflow.com/a/28550013/4342099 .

Try to extend BaseExpandableListAdapter and override getChildTypeCount() and getChildType()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM