androidexpandablelistadapter

GetChildView is getting refreshed on collapsing and expanding ExpandableListView


I've implemented ExpandableListView which has 3 groups and each group contains one child. Each ChildView contains a SwitchCompat

Whenever I collapse/expand other groups, the Switch listeners are being invoked again. It gets checked again and again at the position where it was unchecked.

For more I'm posting piece of code also:

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

        final ViewHolder viewHolder;

        if (convertView == null) {
            // inflate the layout
            LayoutInflater inflater = ((Activity) activity).getLayoutInflater();
            convertView = inflater.inflate(R.layout.link_wallet_item_child, null);

            // well set up the ViewHolder
            viewHolder = new ViewHolder();
            viewHolder.autoPaySwitch = (SwitchCompat) convertView.findViewById(R.id.autoPay_switch);
            viewHolder.textInputEditText = (TextInputEditText) convertView.findViewById(R.id.limit_inputEdittext);
            viewHolder.okTextView = (TextView) convertView.findViewById(R.id.ok_textView);
            viewHolder.limitCheckBox = (CheckBox) convertView.findViewById(R.id.limit_checkBox);

            // store the holder with the view.
            convertView.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        Wallet wallet = (Wallet) getChild(groupPosition, childPosition);

        //Switch
        if (wallet.isAutoPay()) {
            viewHolder.autoPaySwitch.setChecked(true);
        } else {
            viewHolder.autoPaySwitch.setChecked(false);
        }
        ....
        viewHolder.autoPaySwitch.setOnCheckedChangeListener
                (new CompoundButton.OnCheckedChangeListener() {
                     @Override
                     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                         if (InternetConnection.checkConnection(activity)) {
                             new UpdateWalletsAutoPayRequest(activity,
                                     walletList.get(groupPosition).getWalletId().toString(),
                                     isChecked);

                         } else {
                             Toast.makeText(activity, activity.getString(R.string.internet_error),
                                     Toast.LENGTH_SHORT).show();

                             viewHolder.autoPaySwitch.setChecked(!isChecked);
                         }
                     }
                 }
                );
        ...
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return convertView;
}

And above Listener changes the status of SwitchCompat. Hope I'm able to explain my problem. Thanks in advance.


Solution

  • The listener is being called again because during getChildView you are updating the value of them:

    // This is triggering the listener that you created previously
    if (wallet.isAutoPay()) {
        viewHolder.autoPaySwitch.setChecked(true);
    } else {
        viewHolder.autoPaySwitch.setChecked(false);
    }
    

    In order to fix that, I think you can clear the listener (since you are setting it again later):

    // Clear the listener since you are updating the value but don't need to listen to the callback
    viewHolder.autoPaySwitch.setOnCheckedChangeListener(null);
    if (wallet.isAutoPay()) {
        viewHolder.autoPaySwitch.setChecked(true);
    } else {
        viewHolder.autoPaySwitch.setChecked(false);
    }
    
    // Set the listener again as you are already doing
    viewHolder.autoPaySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
         @Override
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            ...
        }
    });
    

    Note: I'm just trying to fix your issue since there are other ways to do it.