1 /*
<lambda>null2  * Copyright (C) 2024 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.util.AttributeSet
21 import android.widget.ImageView
22 import androidx.preference.Preference
23 import androidx.preference.PreferenceGroup
24 import androidx.preference.PreferenceViewHolder
25 import com.android.settingslib.widget.preference.expandable.R
26 
27 class ExpandablePreference @JvmOverloads constructor(
28     context: Context,
29     attrs: AttributeSet? = null,
30     defStyleAttr: Int = 0,
31     defStyleRes: Int = 0
32 ) : PreferenceGroup(context, attrs, defStyleAttr, defStyleRes), Expandable {
33 
34     private var isExpanded = false
35     private var expandIcon: ImageView? = null
36     private var isDirty = true // Flag to track changes
37 
38     init {
39         layoutResource = com.android.settingslib.widget.theme.R.layout.settingslib_expressive_preference
40         widgetLayoutResource = R.layout.settingslib_widget_expandable_icon
41     }
42 
43     override fun onBindViewHolder(holder: PreferenceViewHolder) {
44         super.onBindViewHolder(holder)
45 
46         holder.isDividerAllowedAbove = false
47         holder.isDividerAllowedBelow = false
48 
49         expandIcon = holder.findViewById(R.id.expand_icon) as ImageView?
50 
51         updateExpandedState()
52 
53         holder.itemView.setOnClickListener { toggleExpansion() }
54     }
55 
56     override fun addPreference(preference: Preference): Boolean {
57         preference.isVisible = isExpanded
58         return super.addPreference(preference)
59     }
60 
61     override fun onPrepareAddPreference(preference: Preference): Boolean {
62         preference.isVisible = isExpanded
63         return super.onPrepareAddPreference(preference)
64     }
65 
66     override fun isExpanded(): Boolean {
67         return isExpanded
68     }
69 
70     private fun toggleExpansion() {
71         isExpanded = !isExpanded
72         isDirty = true // Mark as dirty when expansion state changes
73         updateExpandedState()
74         notifyChanged()
75     }
76 
77     private fun updateExpandedState() {
78         expandIcon?.rotation = when (isExpanded) {
79             true -> ROTATION_EXPANDED
80             false -> ROTATION_COLLAPSED
81         }
82 
83         if (isDirty) {
84             (0 until preferenceCount).forEach { i ->
85                 getPreference(i).isVisible = isExpanded
86             }
87             isDirty = false
88         }
89     }
90 
91     companion object {
92         private const val ROTATION_EXPANDED = 180f
93         private const val ROTATION_COLLAPSED = 0f
94     }
95 }