Loading packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml +12 −1 Original line number Diff line number Diff line Loading @@ -41,9 +41,20 @@ android:ellipsize="end" android:textAppearance="@style/TextAppearance.TopIntroText"/> <com.android.settingslib.widget.LinkableTextView android:id="@+id/settingslib_expressive_learn_more" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@android:id/title" app:layout_constraintStart_toStartOf="parent" android:textAlignment="viewStart" android:clickable="true" android:visibility="gone" style="@style/SettingslibTextAppearance.LinkableTextStyle.Expressive"/> <com.google.android.material.button.MaterialButton android:id="@+id/collapse_button" app:layout_constraintTop_toBottomOf="@android:id/title" app:layout_constraintTop_toBottomOf="@id/settingslib_expressive_learn_more" app:layout_constraintStart_toStartOf="parent" android:text="@string/settingslib_expressive_text_expand" app:icon="@drawable/settingslib_expressive_icon_expand" Loading packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml +6 −0 Original line number Diff line number Diff line Loading @@ -329,4 +329,10 @@ <item name="android:textDirection">locale</item> <item name="android:textAppearance">@style/TextAppearance.EntityHeaderTitle</item> </style> <style name="SettingslibTextAppearance.LinkableTextStyle.Expressive" parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textSize">14sp</item> <item name="android:textColor">?android:attr/colorAccent</item> </style> </resources> No newline at end of file packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/CollapsableTextView.kt +58 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.settingslib.widget import android.content.Context import android.graphics.drawable.Drawable import android.text.SpannableString import android.text.TextUtils import android.text.style.URLSpan import android.util.AttributeSet import android.view.Gravity import android.view.LayoutInflater Loading @@ -40,12 +43,18 @@ class CollapsableTextView @JvmOverloads constructor( private val titleTextView: TextView private val collapseButton: MaterialButton private val collapseButtonResources: CollapseButtonResources private var learnMoreListener: View.OnClickListener? = null private var learnMoreText: CharSequence? = null private var learnMoreSpan: LearnMoreSpan? = null val learnMoreTextView: LinkableTextView var isLearnMoreEnabled: Boolean = false init { LayoutInflater.from(context) .inflate(R.layout.settingslib_expressive_collapsable_textview, this) titleTextView = findViewById(android.R.id.title) collapseButton = findViewById(R.id.collapse_button) learnMoreTextView = findViewById(R.id.settingslib_expressive_learn_more) collapseButtonResources = CollapseButtonResources( context.getDrawable(R.drawable.settingslib_expressive_icon_collapse)!!, Loading Loading @@ -111,6 +120,45 @@ class CollapsableTextView @JvmOverloads constructor( updateView() } /** * Sets the action when clicking on the learn more view. * @param listener The click listener for learn more. */ fun setLearnMoreAction(listener: View.OnClickListener?) { if (learnMoreListener != listener) { learnMoreListener = listener formatLearnMoreText() } } /** * Sets the text of learn more view. * @param text The text of learn more. */ fun setLearnMoreText(text: CharSequence?) { if (!TextUtils.equals(learnMoreText, text)) { learnMoreText = text formatLearnMoreText() } } private fun formatLearnMoreText() { if (learnMoreListener == null || TextUtils.isEmpty(learnMoreText)) { learnMoreTextView.visibility = GONE isLearnMoreEnabled = false return } val spannableLearnMoreText = SpannableString(learnMoreText) if (learnMoreSpan != null) { spannableLearnMoreText.removeSpan(learnMoreSpan) } learnMoreSpan = LearnMoreSpan(clickListener = learnMoreListener!!) spannableLearnMoreText.setSpan(learnMoreSpan, 0, learnMoreText!!.length, 0) learnMoreTextView.setText(spannableLearnMoreText) learnMoreTextView.visibility = VISIBLE isLearnMoreEnabled = true } private fun updateView() { when { isCollapsed -> { Loading @@ -130,6 +178,7 @@ class CollapsableTextView @JvmOverloads constructor( } } collapseButton.visibility = if (isCollapsable) VISIBLE else GONE learnMoreTextView.visibility = if (isLearnMoreEnabled && !isCollapsed) VISIBLE else GONE } private data class CollapseButtonResources( Loading @@ -148,3 +197,12 @@ class CollapsableTextView @JvmOverloads constructor( } } internal class LearnMoreSpan( val url: String = "", val clickListener: View.OnClickListener) : URLSpan(url) { override fun onClick(widget: View) { if (clickListener != null) { clickListener.onClick(widget) } } } packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/LinkableTextView.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * 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.settingslib.widget import android.content.Context import android.text.Spanned import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.util.AttributeSet import android.widget.TextView class LinkableTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : TextView(context, attrs, defStyleAttr) { override fun setText(text: CharSequence, type: BufferType?) { super.setText(text, type) if (text is Spanned) { val spans = text.getSpans(0, text.length, ClickableSpan::class.java) if (spans.size > 0) { movementMethod = LinkMovementMethod.getInstance() } } } } No newline at end of file packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.kt +32 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.settingslib.widget import android.content.Context import android.os.Build import android.text.TextUtils import android.util.AttributeSet import android.view.View import androidx.annotation.RequiresApi import androidx.preference.Preference import androidx.preference.PreferenceViewHolder Loading @@ -33,6 +35,8 @@ open class TopIntroPreference @JvmOverloads constructor( private var isCollapsable: Boolean = false private var minLines: Int = 2 private var learnMoreListener: View.OnClickListener? = null private var learnMoreText: CharSequence? = null init { if (SettingsThemeHelper.isExpressiveTheme(context)) { Loading Loading @@ -71,6 +75,10 @@ open class TopIntroPreference @JvmOverloads constructor( setCollapsable(isCollapsable) setMinLines(minLines) setText(title.toString()) if (learnMoreListener != null) { setLearnMoreText(learnMoreText) setLearnMoreAction(learnMoreListener) } } } Loading @@ -94,6 +102,30 @@ open class TopIntroPreference @JvmOverloads constructor( notifyChanged() } /** * Sets the action when clicking on the learn more view. * @param listener The click listener for learn more. */ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) fun setLearnMoreAction(listener: View.OnClickListener) { if (learnMoreListener != listener) { learnMoreListener = listener notifyChanged() } } /** * Sets the text of learn more view. * @param text The text of learn more. */ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) fun setLearnMoreText(text: CharSequence) { if (!TextUtils.equals(learnMoreText, text)) { learnMoreText = text notifyChanged() } } companion object { private const val DEFAULT_MAX_LINES = 10 private const val DEFAULT_MIN_LINES = 2 Loading Loading
packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml +12 −1 Original line number Diff line number Diff line Loading @@ -41,9 +41,20 @@ android:ellipsize="end" android:textAppearance="@style/TextAppearance.TopIntroText"/> <com.android.settingslib.widget.LinkableTextView android:id="@+id/settingslib_expressive_learn_more" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@android:id/title" app:layout_constraintStart_toStartOf="parent" android:textAlignment="viewStart" android:clickable="true" android:visibility="gone" style="@style/SettingslibTextAppearance.LinkableTextStyle.Expressive"/> <com.google.android.material.button.MaterialButton android:id="@+id/collapse_button" app:layout_constraintTop_toBottomOf="@android:id/title" app:layout_constraintTop_toBottomOf="@id/settingslib_expressive_learn_more" app:layout_constraintStart_toStartOf="parent" android:text="@string/settingslib_expressive_text_expand" app:icon="@drawable/settingslib_expressive_icon_expand" Loading
packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml +6 −0 Original line number Diff line number Diff line Loading @@ -329,4 +329,10 @@ <item name="android:textDirection">locale</item> <item name="android:textAppearance">@style/TextAppearance.EntityHeaderTitle</item> </style> <style name="SettingslibTextAppearance.LinkableTextStyle.Expressive" parent="@android:style/TextAppearance.DeviceDefault.WindowTitle"> <item name="android:textSize">14sp</item> <item name="android:textColor">?android:attr/colorAccent</item> </style> </resources> No newline at end of file
packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/CollapsableTextView.kt +58 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.settingslib.widget import android.content.Context import android.graphics.drawable.Drawable import android.text.SpannableString import android.text.TextUtils import android.text.style.URLSpan import android.util.AttributeSet import android.view.Gravity import android.view.LayoutInflater Loading @@ -40,12 +43,18 @@ class CollapsableTextView @JvmOverloads constructor( private val titleTextView: TextView private val collapseButton: MaterialButton private val collapseButtonResources: CollapseButtonResources private var learnMoreListener: View.OnClickListener? = null private var learnMoreText: CharSequence? = null private var learnMoreSpan: LearnMoreSpan? = null val learnMoreTextView: LinkableTextView var isLearnMoreEnabled: Boolean = false init { LayoutInflater.from(context) .inflate(R.layout.settingslib_expressive_collapsable_textview, this) titleTextView = findViewById(android.R.id.title) collapseButton = findViewById(R.id.collapse_button) learnMoreTextView = findViewById(R.id.settingslib_expressive_learn_more) collapseButtonResources = CollapseButtonResources( context.getDrawable(R.drawable.settingslib_expressive_icon_collapse)!!, Loading Loading @@ -111,6 +120,45 @@ class CollapsableTextView @JvmOverloads constructor( updateView() } /** * Sets the action when clicking on the learn more view. * @param listener The click listener for learn more. */ fun setLearnMoreAction(listener: View.OnClickListener?) { if (learnMoreListener != listener) { learnMoreListener = listener formatLearnMoreText() } } /** * Sets the text of learn more view. * @param text The text of learn more. */ fun setLearnMoreText(text: CharSequence?) { if (!TextUtils.equals(learnMoreText, text)) { learnMoreText = text formatLearnMoreText() } } private fun formatLearnMoreText() { if (learnMoreListener == null || TextUtils.isEmpty(learnMoreText)) { learnMoreTextView.visibility = GONE isLearnMoreEnabled = false return } val spannableLearnMoreText = SpannableString(learnMoreText) if (learnMoreSpan != null) { spannableLearnMoreText.removeSpan(learnMoreSpan) } learnMoreSpan = LearnMoreSpan(clickListener = learnMoreListener!!) spannableLearnMoreText.setSpan(learnMoreSpan, 0, learnMoreText!!.length, 0) learnMoreTextView.setText(spannableLearnMoreText) learnMoreTextView.visibility = VISIBLE isLearnMoreEnabled = true } private fun updateView() { when { isCollapsed -> { Loading @@ -130,6 +178,7 @@ class CollapsableTextView @JvmOverloads constructor( } } collapseButton.visibility = if (isCollapsable) VISIBLE else GONE learnMoreTextView.visibility = if (isLearnMoreEnabled && !isCollapsed) VISIBLE else GONE } private data class CollapseButtonResources( Loading @@ -148,3 +197,12 @@ class CollapsableTextView @JvmOverloads constructor( } } internal class LearnMoreSpan( val url: String = "", val clickListener: View.OnClickListener) : URLSpan(url) { override fun onClick(widget: View) { if (clickListener != null) { clickListener.onClick(widget) } } }
packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/LinkableTextView.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * 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.settingslib.widget import android.content.Context import android.text.Spanned import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.util.AttributeSet import android.widget.TextView class LinkableTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : TextView(context, attrs, defStyleAttr) { override fun setText(text: CharSequence, type: BufferType?) { super.setText(text, type) if (text is Spanned) { val spans = text.getSpans(0, text.length, ClickableSpan::class.java) if (spans.size > 0) { movementMethod = LinkMovementMethod.getInstance() } } } } No newline at end of file
packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.kt +32 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.settingslib.widget import android.content.Context import android.os.Build import android.text.TextUtils import android.util.AttributeSet import android.view.View import androidx.annotation.RequiresApi import androidx.preference.Preference import androidx.preference.PreferenceViewHolder Loading @@ -33,6 +35,8 @@ open class TopIntroPreference @JvmOverloads constructor( private var isCollapsable: Boolean = false private var minLines: Int = 2 private var learnMoreListener: View.OnClickListener? = null private var learnMoreText: CharSequence? = null init { if (SettingsThemeHelper.isExpressiveTheme(context)) { Loading Loading @@ -71,6 +75,10 @@ open class TopIntroPreference @JvmOverloads constructor( setCollapsable(isCollapsable) setMinLines(minLines) setText(title.toString()) if (learnMoreListener != null) { setLearnMoreText(learnMoreText) setLearnMoreAction(learnMoreListener) } } } Loading @@ -94,6 +102,30 @@ open class TopIntroPreference @JvmOverloads constructor( notifyChanged() } /** * Sets the action when clicking on the learn more view. * @param listener The click listener for learn more. */ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) fun setLearnMoreAction(listener: View.OnClickListener) { if (learnMoreListener != listener) { learnMoreListener = listener notifyChanged() } } /** * Sets the text of learn more view. * @param text The text of learn more. */ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) fun setLearnMoreText(text: CharSequence) { if (!TextUtils.equals(learnMoreText, text)) { learnMoreText = text notifyChanged() } } companion object { private const val DEFAULT_MAX_LINES = 10 private const val DEFAULT_MIN_LINES = 2 Loading