Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3437090a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[Expressive design] support learn more" into main

parents 7d31ec94 54d324e7
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -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"
+6 −0
Original line number Diff line number Diff line
@@ -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
+58 −0
Original line number Diff line number Diff line
@@ -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
@@ -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)!!,
@@ -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 -> {
@@ -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(
@@ -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)
        }
    }
}
+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
+32 −0
Original line number Diff line number Diff line
@@ -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
@@ -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)) {
@@ -71,6 +75,10 @@ open class TopIntroPreference @JvmOverloads constructor(
            setCollapsable(isCollapsable)
            setMinLines(minLines)
            setText(title.toString())
            if (learnMoreListener != null) {
                setLearnMoreText(learnMoreText)
                setLearnMoreAction(learnMoreListener)
            }
        }
    }

@@ -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