Question

This is not so much of a problem but I am trying to find a correct way of doing this.

I have the following situation:

public class SettingsDialogFragment extends DialogFragment implements OnCheckedChangeListener {

...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.settings, container);

    ...

    CheckBox lBox1  = (CheckBox)view.findViewById(R.id.checkBox1);

    lBox1.setOnCheckedChangeListener(this);
    lBox1.setChecked(true);

    return view;
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

    ....

}

The "problem" I have is that by calling setChecked(true) the onCheckChanged will already fire. I guess that when I inflate the layout - the CheckBox is initialised with a false setting and me changing that to true indeed is a CheckedChanged event.

I could of course change the order and assign the listener after I set the initial value, but is there a way to inflate the layout whilst somehow passing the initial values for the various components? They are dynamic so I cannot fix the values to a particular value in the settings.xml

Cheers

Was it helpful?

Solution 3

The code of the CheckBox looks something like this:

public void setChecked(boolean checked) {
    if (mChecked != checked) {
        mChecked = checked;
        refreshDrawableState();

        // Avoid infinite recursions if setChecked() is called from a listener
        if (mBroadcasting) {
            return;
        }

        mBroadcasting = true;
        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
        }
        if (mOnCheckedChangeWidgetListener != null) {
            mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
        }

        mBroadcasting = false;            
    }
}

So basically you cannot use the method without firing events, unless you remove or disable the event handler before (or set them afterwards only).

OTHER TIPS

The above suggestion is good, but this problem still exists in a checkable ListView. I solved it in this way: disable the listener, set check state, and then set listener again. Here is a helper function:

private void checkCheckBox(CheckBox checkBox, boolean checked) {
    checkBox.setOnCheckedChangeListener(null);
    checkBox.setChecked(checked);
    checkBox.setOnCheckedChangeListener(this);
}

You've answered your own question, the setChecked(true) is causing the OnCheckedChangeListener to be called.

A simple fix would be to add android:checked="true" to your CheckBox XML declaration and omit the setChecked(true) call.

If you just want to set initial values, then your first suggestion is probably the best: just register the listeners after you have initialized everything.

The solution is the OnTouchListener. By default you don't set the OnCheckedChangeListener. What you have to do is the following:

**declared in the class object declaration**:
OnCheckedChangeListener onCheckedChangeListener = new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            **have fun**
        }
    };

**used to the point you would have set the OnCheckedChangeListener**
anyView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                anyUsableView.setOnCheckedChangeListener(onCheckedChangeListener);

                return false;
            }
        });

The return false to the OnTouchListener is very important, otherwise the view will not work anymore.

Tip: this solution can be used with any kind of listener that is good for it (I am using it with a Switch widget)

I guess the solution could be a setChecked() function which detaches the listener before setting the checked value.

public void setCheckedNoEvent(boolean checked) {
    if (onCheckedChangeListener == null) {
        switcher.setChecked(checked);
    } else {
        switcher.setOnCheckedChangeListener(null);
        switcher.setChecked(checked);
        switcher.setOnCheckedChangeListener(OnCheckedChangeListener);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top