1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settingslib.widget; 18 19 import android.content.Context; 20 import android.content.res.TypedArray; 21 import android.util.AttributeSet; 22 import android.widget.Switch; 23 24 import androidx.preference.PreferenceViewHolder; 25 import androidx.preference.TwoStatePreference; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * MainSwitchPreference is a Preference with a customized Switch. 32 * This component is used as the main switch of the page 33 * to enable or disable the prefereces on the page. 34 */ 35 public class MainSwitchPreference extends TwoStatePreference implements OnMainSwitchChangeListener { 36 37 private final List<OnMainSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>(); 38 39 private MainSwitchBar mMainSwitchBar; 40 MainSwitchPreference(Context context)41 public MainSwitchPreference(Context context) { 42 super(context); 43 init(context, null); 44 } 45 MainSwitchPreference(Context context, AttributeSet attrs)46 public MainSwitchPreference(Context context, AttributeSet attrs) { 47 super(context, attrs); 48 init(context, attrs); 49 } 50 MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr)51 public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { 52 super(context, attrs, defStyleAttr); 53 init(context, attrs); 54 } 55 MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)56 public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, 57 int defStyleRes) { 58 super(context, attrs, defStyleAttr, defStyleRes); 59 init(context, attrs); 60 } 61 62 @Override onBindViewHolder(PreferenceViewHolder holder)63 public void onBindViewHolder(PreferenceViewHolder holder) { 64 super.onBindViewHolder(holder); 65 66 holder.setDividerAllowedAbove(false); 67 holder.setDividerAllowedBelow(false); 68 69 mMainSwitchBar = (MainSwitchBar) holder.findViewById(R.id.settingslib_main_switch_bar); 70 // To support onPreferenceChange callback, it needs to call callChangeListener() when 71 // MainSwitchBar is clicked. 72 mMainSwitchBar.setOnClickListener((view) -> callChangeListener(isChecked())); 73 setIconSpaceReserved(isIconSpaceReserved()); 74 updateStatus(isChecked()); 75 registerListenerToSwitchBar(); 76 } 77 init(Context context, AttributeSet attrs)78 private void init(Context context, AttributeSet attrs) { 79 setLayoutResource(R.layout.settingslib_main_switch_layout); 80 mSwitchChangeListeners.add(this); 81 if (attrs != null) { 82 final TypedArray a = context.obtainStyledAttributes(attrs, 83 androidx.preference.R.styleable.Preference, 0 /*defStyleAttr*/, 84 0 /*defStyleRes*/); 85 final CharSequence title = a.getText( 86 androidx.preference.R.styleable.Preference_android_title); 87 setTitle(title); 88 89 final boolean bIconSpaceReserved = a.getBoolean( 90 androidx.preference.R.styleable.Preference_android_iconSpaceReserved, true); 91 setIconSpaceReserved(bIconSpaceReserved); 92 a.recycle(); 93 } 94 } 95 96 @Override setChecked(boolean checked)97 public void setChecked(boolean checked) { 98 super.setChecked(checked); 99 if (mMainSwitchBar != null && mMainSwitchBar.isChecked() != checked) { 100 mMainSwitchBar.setChecked(checked); 101 } 102 } 103 104 @Override setTitle(CharSequence title)105 public void setTitle(CharSequence title) { 106 super.setTitle(title); 107 if (mMainSwitchBar != null) { 108 mMainSwitchBar.setTitle(title); 109 } 110 } 111 112 @Override setIconSpaceReserved(boolean iconSpaceReserved)113 public void setIconSpaceReserved(boolean iconSpaceReserved) { 114 super.setIconSpaceReserved(iconSpaceReserved); 115 if (mMainSwitchBar != null) { 116 mMainSwitchBar.setIconSpaceReserved(iconSpaceReserved); 117 } 118 } 119 120 @Override onSwitchChanged(Switch switchView, boolean isChecked)121 public void onSwitchChanged(Switch switchView, boolean isChecked) { 122 super.setChecked(isChecked); 123 } 124 125 /** 126 * Update the switch status of preference 127 */ updateStatus(boolean checked)128 public void updateStatus(boolean checked) { 129 setChecked(checked); 130 if (mMainSwitchBar != null) { 131 mMainSwitchBar.setTitle(getTitle()); 132 mMainSwitchBar.show(); 133 } 134 } 135 136 /** 137 * Adds a listener for switch changes 138 */ addOnSwitchChangeListener(OnMainSwitchChangeListener listener)139 public void addOnSwitchChangeListener(OnMainSwitchChangeListener listener) { 140 if (!mSwitchChangeListeners.contains(listener)) { 141 mSwitchChangeListeners.add(listener); 142 } 143 144 if (mMainSwitchBar != null) { 145 mMainSwitchBar.addOnSwitchChangeListener(listener); 146 } 147 } 148 149 /** 150 * Remove a listener for switch changes 151 */ removeOnSwitchChangeListener(OnMainSwitchChangeListener listener)152 public void removeOnSwitchChangeListener(OnMainSwitchChangeListener listener) { 153 mSwitchChangeListeners.remove(listener); 154 if (mMainSwitchBar != null) { 155 mMainSwitchBar.removeOnSwitchChangeListener(listener); 156 } 157 } 158 registerListenerToSwitchBar()159 private void registerListenerToSwitchBar() { 160 for (OnMainSwitchChangeListener listener : mSwitchChangeListeners) { 161 mMainSwitchBar.addOnSwitchChangeListener(listener); 162 } 163 } 164 } 165