naeemgik
naeemgik

Reputation: 2272

Repeating children in Expandable listView android

I am developing three level expandable listview in android. but my child nodes are populating in duplicate order. Here is my source code:

public class CarPanel extends ExpandableListActivity {

    static ArrayList<String> groupItem = new ArrayList<String>();
    static ArrayList<String> childItem = new ArrayList<String>();
    static ArrayList<Object> grandChildItem = new ArrayList<Object>();
    static public ArrayList<String> childValue;
    static public ArrayList<String> grandChildValue;

    EditText modelType, price, dyp, insurance;

    static int dummyFlag = 0;
    public LayoutInflater minflater;
    public Activity activity;

    private MyDBManager dbManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);     
        //Remove title bar
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        //Remove notification bar    
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        dbManager = new MyDBManager(this);
        dbManager.open();

        ExpandableListView expandbleLis = getExpandableListView();
        expandbleLis.setDividerHeight(2);
        expandbleLis.setGroupIndicator(null);
        expandbleLis.setClickable(true);

        // 1st level data       
        setGroupData();

        // 2nd level data
        setChildGroupData();

        // 3rd level data
        setGrandChildGroupData();

        ParentLevel parentAdapter = new ParentLevel(groupItem);
        parentAdapter.setInflater((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE), this);
        getExpandableListView().setAdapter(parentAdapter);
        expandbleLis.setOnChildClickListener(this);

    }

    public class ParentLevel extends BaseExpandableListAdapter {


        public ParentLevel(ArrayList<String> groupList) {
             groupItem = groupList;
        }

        public Object getChild(int arg0, int arg1) {
            return arg1;
        }

        public void setInflater(LayoutInflater mInflater, Activity act) {
            minflater = mInflater;
            activity = act;
        }


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


        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            CustExpListview SecondLevelexplv = new CustExpListview(CarPanel.this);
            SecondLevelexplv.setAdapter(new SecondLevelAdapter(childItem, grandChildItem ));
            SecondLevelexplv.setGroupIndicator(null);

            return SecondLevelexplv;
        }


        public int getChildrenCount(int groupPosition) {
            Log.v("childItem.size()", "childItem.size()  " +childItem.size());
            return childItem.size();
        }


        public Object getGroup(int groupPosition) {
            return groupPosition;
        }


        public int getGroupCount() {
            Log.v("groupItem.size()", "groupItem.size()  " +groupItem.size());
            return groupItem.size();
        }


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

        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = minflater.inflate(R.layout.grouprow, null);
            }
            ((CheckedTextView) convertView).setText(groupItem.get(groupPosition));
            ((CheckedTextView) convertView).setChecked(isExpanded);
            return convertView;
        }


        public boolean hasStableIds() {
            return true;
        }


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

    class CustExpListview extends ExpandableListView {

        int intGroupPosition, intChildPosition, intGroupid;

        public CustExpListview(Context context) {
            super(context);
        }

        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(600,MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    class SecondLevelAdapter extends BaseExpandableListAdapter {

        public LayoutInflater minflater;
        public Context activity;

    public SecondLevelAdapter(ArrayList<String> childList, ArrayList<Object> grandChildList) {
            childItem = childList;
            grandChildItem = grandChildList;
        }

        public void setInflater(LayoutInflater mInflater, Context parentLevel) {
            minflater = mInflater;
            activity = parentLevel;
        }

        public Object getChild(int groupPosition, int childPosition) {
            return childPosition;
        }


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


        @SuppressWarnings("unchecked")
        public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            grandChildValue = (ArrayList<String>) grandChildItem.get(groupPosition);
            EditText modelType, price, dyp, insurance;
            if (convertView == null) {
                 LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = layoutInflater.inflate(R.layout.grandchildrow, null);
            }

            modelType = (EditText) convertView.findViewById(R.id.et_ModelType);
            price = (EditText) convertView.findViewById(R.id.et_Price);
            dyp = (EditText) convertView.findViewById(R.id.et_DYP);
            insurance = (EditText) convertView.findViewById(R.id.et_Insurance);

            modelType.setText(grandChildValue.get(childPosition));

            convertView.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    Toast.makeText(getBaseContext(), grandChildValue.get(childPosition), Toast.LENGTH_SHORT).show();
                }
            });


            return convertView;
        }


        public int getChildrenCount(int groupPosition) {
            return ((ArrayList<String>) grandChildItem.get(groupPosition)).size();
        }


        public Object getGroup(int groupPosition) {
            return groupPosition;
        }

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


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


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

            if (convertView == null) {
                LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = layoutInflater.inflate(R.layout.childrow, null);
            }
            ((CheckedTextView) convertView).setText(childItem.get(groupPosition));
            ((CheckedTextView) convertView).setChecked(isExpanded);
            return convertView;

        }


        public boolean hasStableIds() {
            return true;
        }


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

    }

    public void setGroupData() {
        groupItem.clear();

        Cursor cursor = dbManager.execQuery("SELECT DISTINCT carName FROM model");
        final List<ModelBean> modelList = new ArrayList<ModelBean>();
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            ModelBean beanObj = cursorToModel(cursor);
            modelList.add(beanObj);
            cursor.moveToNext();
        }
        // Make sure to close the cursor
        cursor.close();
        ModelBean modelObj = null;

        if (modelList.size() > 0 )
        {
            for (int i = 0; i < modelList.size(); i++)
            {
                modelObj = modelList.get(i);
                String carName = modelObj.getCarName();             
                groupItem.add(carName);
            }
        }
    }     

    public void setChildGroupData() {

        childItem.clear();

        childItem.add("Android");

        childItem.add("iOS");

        childItem.add("HTC");

    }

    public void setGrandChildGroupData() {
        grandChildItem.clear();

        ArrayList<String> child = new ArrayList<String>();
        child.add("PASSAT 1");
        child.add("PASSAT 2");
        grandChildItem.add(child);

        child = new ArrayList<String>();
        child.add("POLO 1");
        child.add("POLO 2");
        grandChildItem.add(child);

        child = new ArrayList<String>();
        child.add("VITZ 1");
        child.add("VITZ 2");
        grandChildItem.add(child);

    }

    private ModelBean cursorToModel(Cursor cursor) 
       {
          ModelBean modelBean = new ModelBean();
          modelBean.setCarName(cursor.getString(0));

         return modelBean;
        } 
}

Now I want this code of block to repeat only once for each parent group however it repeat three times. I have searched much more and similar SO questions but did not came into solution.

Android

iOS

HTC

Upvotes: 4

Views: 3221

Answers (1)

phpslightly
phpslightly

Reputation: 314

I struggled with this same problem and could not find the solution anywhere online/SO.

After doing some logging I came to the conclusion that the parent level BaseExpandbleAdapater will call/create a childView corresponding to the number of children in your dataset/group. Unfortunately this is not desired in a three-level nested list scenario.

So when generating a Three-level list, simply make the function getChildrenCount in the parent adapter like this:

    @Override
    public int getChildrenCount(int groupPosition){
         return 1;
    }

Now it will only build "1" iteration of children list items, even though the 1 nested list can contain any number of children, which from the view point of the child adapater then becomes the group.

It is confusing because your child/nested adapter handles displaying the actual "children", whereas in a single nested list, you children are handled within that same parent adapter class. In this scenario the child/nested adapter is going to handle displaying what would be the children as its own groupView, making the number of children in the parent adapter irrelevant. At least that is what my results and environment are showing me...

Hope I could be of help, this had me stumped for a good half a day.

Upvotes: 10

Related Questions