16904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project
36904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
46904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
56904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * you may not use this file except in compliance with the License.
66904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * You may obtain a copy of the License at
76904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
86904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
96904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Unless required by applicable law or agreed to in writing, software
116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * See the License for the specific language governing permissions and
14ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * limitations under the License.
156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */
166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.preference;
186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.Context;
226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.res.TypedArray;
236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.util.AttributeSet;
246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.View;
25c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslavimport android.view.accessibility.AccessibilityManager;
266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.widget.Checkable;
272c15890a010232b8625788629fa14923fdd6ec5bScott Kennedyimport android.widget.CompoundButton;
286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
29ca95d1c53dd086c368cd21685179517d4dadabcdAurimas Liutikasimport androidx.annotation.RestrictTo;
30ca95d1c53dd086c368cd21685179517d4dadabcdAurimas Liutikasimport androidx.core.content.res.TypedArrayUtils;
31ca95d1c53dd086c368cd21685179517d4dadabcdAurimas Liutikas
326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/**
336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * A {@link Preference} that provides checkbox widget
346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * functionality.
356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>
366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * This preference will store a boolean into the SharedPreferences.
376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
38929f27aab7ac7231f3734c988d5ee7201627d535Alan Viverette * @attr name android:summaryOff
39929f27aab7ac7231f3734c988d5ee7201627d535Alan Viverette * @attr name android:summaryOn
40929f27aab7ac7231f3734c988d5ee7201627d535Alan Viverette * @attr name android:disableDependentsState
416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */
426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpublic class CheckBoxPreference extends TwoStatePreference {
432c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy    private final Listener mListener = new Listener();
442c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy
452c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy    private class Listener implements CompoundButton.OnCheckedChangeListener {
462c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        @Override
472c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
482c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy            if (!callChangeListener(isChecked)) {
492c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy                // Listener didn't like it, change it back.
502c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy                // CompoundButton will make sure we don't recurse.
512c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy                buttonView.setChecked(!isChecked);
522c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy                return;
532c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy            }
542c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy            CheckBoxPreference.this.setChecked(isChecked);
552c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        }
562c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy    }
576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public CheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        this(context, attrs, defStyleAttr, 0);
606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public CheckBoxPreference(
636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super(context, attrs, defStyleAttr, defStyleRes);
656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final TypedArray a = context.obtainStyledAttributes(attrs,
676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                R.styleable.CheckBoxPreference, defStyleAttr, defStyleRes);
6884765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
6984765eaea7da18d0576db557959129e9d0db8e8cTony Mantler        setSummaryOn(TypedArrayUtils.getString(a, R.styleable.CheckBoxPreference_summaryOn,
7084765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                R.styleable.CheckBoxPreference_android_summaryOn));
7184765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
7284765eaea7da18d0576db557959129e9d0db8e8cTony Mantler        setSummaryOff(TypedArrayUtils.getString(a, R.styleable.CheckBoxPreference_summaryOff,
7384765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                R.styleable.CheckBoxPreference_android_summaryOff));
7484765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
7584765eaea7da18d0576db557959129e9d0db8e8cTony Mantler        setDisableDependentsState(TypedArrayUtils.getBoolean(a,
7684765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                R.styleable.CheckBoxPreference_disableDependentsState,
7784765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                R.styleable.CheckBoxPreference_android_disableDependentsState, false));
7884765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        a.recycle();
806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public CheckBoxPreference(Context context, AttributeSet attrs) {
833fadd62b614e4a69aefe920aac640bdb629e502eJason Monk        this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.checkBoxPreferenceStyle,
843fadd62b614e4a69aefe920aac640bdb629e502eJason Monk                android.R.attr.checkBoxPreferenceStyle));
856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public CheckBoxPreference(Context context) {
886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        this(context, null);
896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
92671d9d6db5c64e6c8392e56fb84a181ca0550469Tony Mantler    public void onBindViewHolder(PreferenceViewHolder holder) {
936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onBindViewHolder(holder);
946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
952c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        syncCheckboxView(holder.findViewById(android.R.id.checkbox));
966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        syncSummaryView(holder);
986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
99c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav
100c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    /**
101c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav     * @hide
102c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav     */
1038e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas    @RestrictTo(LIBRARY_GROUP)
104c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    @Override
105c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    protected void performClick(View view) {
106c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        super.performClick(view);
107c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        syncViewIfAccessibilityEnabled(view);
108c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    }
109c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav
110c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    private void syncViewIfAccessibilityEnabled(View view) {
111c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        AccessibilityManager accessibilityManager = (AccessibilityManager)
112c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav                getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
113c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        if (!accessibilityManager.isEnabled()) {
114c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav            return;
115c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        }
116c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav
11790d56ef3b34db86c9b775e910db38b6b81a170cdTony Mantler        View checkboxView = view.findViewById(android.R.id.checkbox);
118c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        syncCheckboxView(checkboxView);
119c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav
120c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        View summaryView = view.findViewById(android.R.id.summary);
121c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        syncSummaryView(summaryView);
122c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    }
123c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav
124c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    private void syncCheckboxView(View view) {
1252c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        if (view instanceof CompoundButton) {
1262c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy            ((CompoundButton) view).setOnCheckedChangeListener(null);
1272c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        }
128c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        if (view instanceof Checkable) {
129c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav            ((Checkable) view).setChecked(mChecked);
130c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav        }
1312c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        if (view instanceof CompoundButton) {
1322c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy            ((CompoundButton) view).setOnCheckedChangeListener(mListener);
1332c15890a010232b8625788629fa14923fdd6ec5bScott Kennedy        }
134c67647d83261aad33d42309c52aa75e05ea9daf7Svetoslav    }
1356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler}
136