Search code examples
androidexpandablelistviewchildviews

Android ExpandableListView using Holder for childViews with SeekBar. childViews are interdepending


I'm trying to realize a layout with an ExpendableListView. There are 4 Group Elements and for each Group 2 Children. The first Group Element does have 0 Children.

G
G
 C
 C
G
 C
 C
G
 C
 C

Every Group Element has 2 TextViews, 1 ImageView and 1 Switch. Every Child Element has 2 TextViews and 1 SeekBar.

The Adapter contains 2 Holder. One for the Groupviews and one for the Childviews.

On the Group Layer everything works as intented.

But on the Child Layer the different ChildViews are interdependend. For example setting the SeekBar of Group Element3/Child Element1 sets the SeekBar of Group Element1/Child Element0 too.

I do understand the problem has something to do with missing uniques of the views and view handling(optimizing) by Android.

Here is the getChildView method:

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

final int tempgroupPos = groupPosition;
final int tempchildPos = childPosition;

ChildViewHolder cviewHolder = null; 

if (convertView == null) {  
    convertView = inflater.inflate(R.layout.interfaces_listrow_details_intervall, null);

    cviewHolder  = new ChildViewHolder();

    cviewHolder.tvb = (TextView) convertView.findViewById(R.id.interfaces_child_intervall_textbig);
    cviewHolder.tvs = (TextView) convertView.findViewById(R.id.interfaces_child_intervall_textexplanation);
    cviewHolder.sb = (SeekBar) convertView.findViewById(R.id.interfacesSeekBar);

    cviewHolder.sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub      
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub      
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {

            int getPosition = (Integer) seekBar.getTag();   

            clist.get(tempgroupPos).get(tempchildPos).setProgress(seekBar.getProgress());

            // do stuff

            notifyDataSetChanged();
        }
    });

    convertView.setTag(cviewHolder);

    convertView.setTag(R.id.interfaces_child_intervall_textbig, cviewHolder.tvb);
    convertView.setTag(R.id.interfaces_child_intervall_textexplanation, cviewHolder.tvs);
    convertView.setTag(R.id.interfacesSeekBar, cviewHolder.sb);

} else {
    cviewHolder = (ChildViewHolder) convertView.getTag();
}

cviewHolder.sb.setTag(groupPosition);
cviewHolder.sb.setProgress(clist.get(groupPosition).get(childPosition).getProgress());

cviewHolder.tvb.setText(clist.get(groupPosition).get(childPosition).getBigText());  
cviewHolder.tvs.setText(clist.get(groupPosition).get(childPosition).getSmallTextActivated());

return convertView;
}

If you need any other part of the code or other informations please ask.

I looked into these Question/Answers but they did not really help me personally.


Solution

  • OK. Besides I am not really sure why this approach won't work I looked again on the posted links to Q/A. I've choosed this one

    Android - Expandable ListView - using ViewHolder for optimization

    and followed everything exactly. Now it works that way. I focused to much on my first choosen example. Thank you. My code is working now. Here is the code for others to refer.

    ChildViewHolder:

    // https://stackoverflow.com/questions/22583689/android-expandable-listview-using-viewholder-for-optimization
    static class ChildViewHolder {
        private HashMap<Integer, View> storedViews = new HashMap<Integer, View>();
    
    
        public ChildViewHolder addView(View view)
        {
            int id = view.getId();
            storedViews.put(id, view);
            return this;
        }
    
        public View getView(int id)
        {
            return storedViews.get(id);
        }
    }
    

    getChildView Method:

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
    
        final int tempgroupPos = groupPosition;
        final int tempchildPos = childPosition;
    
        View row = convertView;
        if (row == null)
        {
            row = inflater.inflate(R.layout.interfaces_listrow_details_intervall, parent, false);
    
            TextView tvb = (TextView) row.findViewById(R.id.interfaces_child_intervall_textbig);
            TextView tvs = (TextView) row.findViewById(R.id.interfaces_child_intervall_textexplanation);
            SeekBar sb = (SeekBar) row.findViewById(R.id.interfacesSeekBar);
    
            ChildViewHolder cholder = new ChildViewHolder();
    
            cholder.addView(tvb);
            cholder.addView(tvs);
            cholder.addView(sb);
    
            row.setTag(cholder);
        }
    
        ChildViewHolder cholder = (ChildViewHolder) row.getTag();
        TextView tvb = (TextView) cholder.getView(R.id.interfaces_child_intervall_textbig);
        TextView tvs = (TextView) cholder.getView(R.id.interfaces_child_intervall_textexplanation);
        SeekBar sb = (SeekBar) cholder.getView(R.id.interfacesSeekBar);
    
        sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
    
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }
    
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub  
            }
    
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
    
                Globals g = Globals.getInstance();
                clist.get(tempgroupPos-1).get(tempchildPos).setProgress(seekBar.getProgress());
    
                // do something
                notifyDataSetChanged();
            }
        });
    
        tvb.setText(clist.get(groupPosition-1).get(childPosition).getBigText());
        tvs.setText(clist.get(groupPosition-1).get(childPosition).getSmallTextActivated());
        sb.setProgress(clist.get(groupPosition-1).get(childPosition).getProgress());
    
        return row;
    }