Pergunta

Hello I am using Android Expandable listview and inflating childs in it with different views. The problem i am having is when i expand a view and then open another parent view the children views in the layout gets messed up and inflates wrong layouts in code. Here is my sample Code for both project.

this is my activity.

 public class MainActivity extends Activity {

List<String> groupList;
List<Integer> childList;
Map<String, List<Integer>> laptopCollection;
ExpandableListView expListView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);

    createGroupList();

    createCollection();

    expListView = (ExpandableListView) findViewById(R.id.laptop_list);
    final ExpandableListAdapter expListAdapter = new ExpandableListAdapter(
            this, groupList, laptopCollection);
    expListView.setAdapter(expListAdapter);
    // setGroupIndicatorToRight();

    // setGroupIndicatorToRight();

    expListView.setOnChildClickListener(new OnChildClickListener() {

        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) {
            final String selected = (String) expListAdapter.getChild(
                    groupPosition, childPosition);
            Toast.makeText(getBaseContext(), selected,  
Toast.LENGTH_LONG)
                    .show();

            return true;
        }
    });

    expListView.setOnGroupExpandListener(new OnGroupExpandListener() {

        private int lastExpandedGroupPosition;

        @Override
        public void onGroupExpand(int groupPosition) {
            // TODO Auto-generated method stub

            if (groupPosition != lastExpandedGroupPosition) {
                expListView.collapseGroup(lastExpandedGroupPosition);
            }

            lastExpandedGroupPosition = groupPosition;
            expListAdapter.notifyDataSetChanged();

        };
    });
}

private void createGroupList() {
    groupList = new ArrayList<String>();
    groupList.add("General Settings");
    groupList.add("Name");
    groupList.add("Password");
    groupList.add("Notifications");
    groupList.add("Profile Settings");
    groupList.add("Change Picture");
    groupList.add("Disable Account");
    /*
     * groupList.add("Sony"); groupList.add("HCL");
     * groupList.add("Samsung");
     */
}

private void createCollection() {
    // preparing laptops collection(child)
    // int[] hpModels = { R.layout.settings_notification,
    // R.layout.settings_newpassword,
    // R.layout.settings_name};
    // int[] dellModels = { R.layout.settings_name ,
    // R.layout.settings_newpassword , R.layout.settings_notification};
    // String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" };
    //
    //

    int[] emptyList = {};
    int[] password = { R.layout.settings_password,
            R.layout.settings_newpassword,        R.layout.settings_repeatpassword };
    int[] noti = { R.layout.settings_notis };
    int[] pic = { R.layout.settings_displaypicture };
    int[] dellModels = { R.layout.settings_name,
            R.layout.settings_newpassword,   R.layout.settings_notification };
    // String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series",
    // "ThinkPad X Series", "Ideapad Z Series" };
    // String[] sonyModels = { "VAIO E Series", "VAIO Z Series",
    // "VAIO S Series", "VAIO YB Series" };
    //
    // String[] samsungModels = { "NP Series", "Series 5", "SF Series" };

    laptopCollection = new LinkedHashMap<String, List<Integer>>();

    for (String laptop : groupList) {
        if (laptop.equals("General Settings")) {
            loadChild(emptyList);
        } else if (laptop.equals("Name"))
            loadChild(emptyList);
        else if (laptop.equals("Password"))
            loadChild(password);
        else if (laptop.equals("Notifications"))
            loadChild(noti);

        else {
            loadChild(emptyList);
        }
        /*
         * else if (laptop.equals("Sony")) loadChild(sonyModels); else if
         * (laptop.equals("HCL")) loadChild(hclModels); else if
         * (laptop.equals("Samsung")) loadChild(samsungModels); else
         * loadChild(lenovoModels);
         */

        laptopCollection.put(laptop, childList);
    }
}

private void loadChild(int[] laptopModels) {
    childList = new ArrayList<Integer>();
    for (Integer model : laptopModels)
        childList.add(model);
}

/*
 * private void setGroupIndicatorToRight() { Get the screen width
 * DisplayMetrics dm = new DisplayMetrics();
 * getWindowManager().getDefaultDisplay().getMetrics(dm); int width =
 * dm.widthPixels;
 * 
 * expListView.setIndicatorBounds(width - getDipsFromPixel(35), width -
 * getDipsFromPixel(5)); }
 */

// Convert pixel to dip
public int getDipsFromPixel(float pixels) {
    // Get the screen's density scale
    final float scale = getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    return (int) (pixels * scale + 0.5f);
}

}

And this is my Adapter for the Expandable Listview

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Activity context;
private Map<String, List<Integer>> laptopCollections;
private List<String> laptops;

public ExpandableListAdapter(Activity context, List<String> laptops,
        Map<String, List<Integer>> laptopCollection) {
    this.context = context;
    this.laptopCollections = laptopCollection;
    this.laptops = laptops;
}

public Object getChild(int groupPosition, int childPosition) {
    return laptopCollections.get(laptops.get(groupPosition)).get(childPosition);
}

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

public View getChildView(final int groupPosition, final int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent) {
    final int laptop = (Integer) getChild(groupPosition, childPosition);
    LayoutInflater inflater = context.getLayoutInflater();

    if (convertView == null) {
        convertView = inflater.inflate(laptop ,null);
    }

   TextView item = (TextView) convertView.findViewById(R.id.laptop);
    item.setText(laptop);
    return convertView;
}

public int getChildrenCount(int groupPosition) {
    return laptopCollections.get(laptops.get(groupPosition)).size();
}

public Object getGroup(int groupPosition) {
    return laptops.get(groupPosition);
}

public int getGroupCount() {
    return laptops.size();
}

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

public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {
    String laptopName = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.grouup_item,
                null);
    }
    TextView item = (TextView) convertView.findViewById(R.id.laptop);
    item.setTypeface(null, Typeface.BOLD);
    item.setText(laptopName);
    return convertView;
}

public boolean hasStableIds() {
    return true;
}

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



}
Foi útil?

Solução

try this.. write this under ExpandablelistAdapter extends BaseExpandablelistAdapter

  public int getViewTypeCount() 
        {
            return 2;//layout number
        }

        public int getItemViewType(int groupposition,int childposition) {


            if (getChildId(groupposition, childposition)!=3) //set condition when it changed
                return 1;//retun layout number


            else 
                return 0;//retun layout number
        }

Outras dicas

In case you are using data binding, refer https://stackoverflow.com/a/51154423/7710739 (Using setTag and getTag solves the issue)

In case you are using

buildFeatures {
        viewBinding true
    }

Try this in both your child and group:

  private var _binding_listitem: ListItemBinding? = null //replace with your binding

    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        var convertViewLocal = convertView
        val expandedListText = getChild(groupPosition, childPosition) as String
        if (convertViewLocal == null) {
            var layoutInflater =
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            _binding_listitem = ListItemBinding.inflate(layoutInflater, convertViewLocal, false)
            convertViewLocal = _binding_listitem?.root

        }else{
            _binding_listitem = convertViewLocal.getTag() as ListItemBinding
        }
        _binding_listitem?.expandedListItem?.text = expandedListText

        convertViewLocal?.setTag(_binding_listitem);

        return convertViewLocal!!
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top