문제

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

도움이 되었습니까?

해결책 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).

다른 팁

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);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top