From 6a52eeabbca3a4bdf72dce3b86ba1a93facf9d62 Mon Sep 17 00:00:00 2001 From: Jacky Wang Date: Tue, 12 Nov 2024 14:05:00 +0800 Subject: [PATCH] [Catalyst] Support main switch bar MainSwitchBar is a view widget in activity layout stick to the top of screen UI. There is no corresponding Preference in the preference screen. For Catalyst support, introduce an invisible Preference object to manipulate with MainSwitchBar, so that the binding mechanism is still working on top of this abstraction. Bug: 332201912 Flag: EXEMPT new class Test: manual Change-Id: If50932a443c1ed3ac04d3ea2e3273724d750297d --- .../android/settings/SettingsActivity.java | 11 ++- .../settings/widget/MainSwitchBarMetadata.kt | 36 +++++++++ .../widget/MainSwitchBarPreference.kt | 79 +++++++++++++++++++ 3 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/com/android/settings/widget/MainSwitchBarMetadata.kt create mode 100644 src/com/android/settings/widget/MainSwitchBarPreference.kt diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index cc6bafb2562..c81d504b223 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -311,6 +311,11 @@ public class SettingsActivity extends SettingsBaseActivity } setContentView(R.layout.settings_main_prefs); + mMainSwitch = findViewById(R.id.switch_bar); + if (mMainSwitch != null) { + mMainSwitch.setMetricsCategory(lookupMetricsCategory()); + mMainSwitch.setTranslationZ(findViewById(R.id.main_content).getTranslationZ() + 1); + } getSupportFragmentManager().addOnBackStackChangedListener(this); @@ -330,12 +335,6 @@ public class SettingsActivity extends SettingsBaseActivity launchSettingFragment(initialFragmentName, intent); } - mMainSwitch = findViewById(R.id.switch_bar); - if (mMainSwitch != null) { - mMainSwitch.setMetricsCategory(lookupMetricsCategory()); - mMainSwitch.setTranslationZ(findViewById(R.id.main_content).getTranslationZ() + 1); - } - // see if we should show Back/Next buttons if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) { diff --git a/src/com/android/settings/widget/MainSwitchBarMetadata.kt b/src/com/android/settings/widget/MainSwitchBarMetadata.kt new file mode 100644 index 00000000000..f55cfd03789 --- /dev/null +++ b/src/com/android/settings/widget/MainSwitchBarMetadata.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.widget + +import android.content.Context +import androidx.preference.Preference +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.TwoStatePreference +import com.android.settingslib.preference.PreferenceBindingPlaceholder +import com.android.settingslib.preference.TwoStatePreferenceBinding + +/** Base metadata of `MainSwitchBar`. */ +interface MainSwitchBarMetadata : + TwoStatePreference, TwoStatePreferenceBinding, PreferenceBindingPlaceholder { + + override fun createWidget(context: Context) = MainSwitchBarPreference(context, this) + + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + (preference as MainSwitchBarPreference).updateVisibility() + } +} diff --git a/src/com/android/settings/widget/MainSwitchBarPreference.kt b/src/com/android/settings/widget/MainSwitchBarPreference.kt new file mode 100644 index 00000000000..6ed887790c8 --- /dev/null +++ b/src/com/android/settings/widget/MainSwitchBarPreference.kt @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.widget + +import android.content.Context +import android.widget.CompoundButton +import android.widget.CompoundButton.OnCheckedChangeListener +import androidx.preference.TwoStatePreference +import com.android.settings.SettingsActivity +import com.android.settingslib.metadata.PreferenceAvailabilityProvider +import com.android.settingslib.widget.MainSwitchBar + +/** Preference abstraction of the [MainSwitchBar] in settings activity. */ +class MainSwitchBarPreference(context: Context, private val metadata: MainSwitchBarMetadata) : + TwoStatePreference(context), OnCheckedChangeListener { + + private val mainSwitchBar: MainSwitchBar = (context as SettingsActivity).switchBar + + override fun setTitle(title: CharSequence?) { + mainSwitchBar.setTitle(title) + } + + override fun setSummary(summary: CharSequence?) { + mainSwitchBar.setSummary(summary) + } + + override fun setEnabled(enabled: Boolean) { + mainSwitchBar.isEnabled = enabled + } + + // Preference.setVisible is final, we cannot override it + fun updateVisibility() { + // always make preference invisible, the UI visibility is reflected on MainSwitchBar + isVisible = false + if ((metadata as? PreferenceAvailabilityProvider)?.isAvailable(context) != false) { + mainSwitchBar.show() + } else { + mainSwitchBar.hide() + } + } + + override fun setChecked(checked: Boolean) { + // remove listener to update UI only + mainSwitchBar.removeOnSwitchChangeListener(this) + mainSwitchBar.isChecked = checked + mainSwitchBar.addOnSwitchChangeListener(this) + } + + override fun onAttached() { + super.onAttached() + mainSwitchBar.addOnSwitchChangeListener(this) + } + + override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { + // prevent user from toggling the switch before data store operation is done + isEnabled = false + // once data store is updated, isEnabled will be reset due to rebind + persistBoolean(isChecked) + } + + override fun onDetached() { + mainSwitchBar.removeOnSwitchChangeListener(this) + super.onDetached() + } +}