0

I have an expandable list view. I use a custom adapter to load my own .xml layout. Each group has a Switch. I don't know how many groups will be displayed. Now I am wondering how to dynamically add a listener to each switch, in order to react on changes.

ExpandableListView Activity:

    public class ExpandableListView extends Activity {

    private MyCustomAdapter adapter;
    private ExpandableListView listView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.detail_layout); 

        initViews();        
    }   

    private void initViews() {

        listView = (ExpandableListView) findViewById(R.id.foo);
        adapter = new MyCustomAdapter(this, data); // my custom adapter
        listView.setAdapter(adapter);

        //...   
    }

    //...   
}

MyCustomAdapter

public class MyCustomAdapter extends BaseExpandableListAdapter {

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

        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_group, null); // load layout with switch
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.myTextView;
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        return convertView;
    }

    // ...
}

list_group.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="8dp"
    android:background="#000000">


    <TextView
        android:id="@+id/myTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:paddingLeft="20dp"
        android:paddingRight="0dp"
        android:paddingEnd="0dp"
        android:paddingStart="20dp"
        android:textSize="17sp" />


    <Switch
        android:id="@+id/mySwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:focusable="false"
        android:checked="true"
     />


</RelativeLayout>

How can I add a listener to each "mySwitch"? Is this possible in ExpandableListView ?

Thanks!

null
  • 1,369
  • 2
  • 18
  • 38

2 Answers2

0

Add a listener when inflating the group layout. And you can distinguish which group's switch was clicked by setting a tag that corresponds to that group position.

Here's an example:

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

        // Add a switch listener
        Switch mySwitch = (Switch) convertView.findViewById(R.id.mySwitch);
        mySwitch.setTag(groupPosition);
        mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Log.e("TAG", "Clicked position: " + buttonView.getTag());
            }
        });
    } else {
        convertView.findViewById(R.id.mySwitch).setTag(groupPosition);
    }

    ...

    return convertView;
}

Note that you need to set the tag each time getGroupView is called.

As a sidenote: you should use a Holder pattern so you don't have to call findViewById (which is costly) in getGroupView.

Simas
  • 43,548
  • 10
  • 88
  • 116
  • Thanks for this pretty simple solution. I thought it might be a problem to set the listener in `getGroupView`, because this method is called over and over again. – null Oct 07 '14 at 06:49
0

First of all you should use the ViewHolder pattern. Why don't you add an OnCheckedChangeListener to your Switch if you inflate your layout? It is possible that you should set the switch unfocusable, in order to still be able to click your list items.

bbrakenhoff
  • 179
  • 1
  • 6
  • Yes, I'll change my code. You're right, because the switch has to be set unfocusable indeed. – null Oct 07 '14 at 06:50