• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.deskclock.settings
18 
19 import android.content.Context
20 import android.util.AttributeSet
21 import android.view.View
22 import android.view.ViewGroup
23 import android.widget.ArrayAdapter
24 import androidx.core.content.ContextCompat
25 import androidx.preference.DropDownPreference
26 
27 import com.android.deskclock.R
28 import com.android.deskclock.Utils
29 
30 /**
31  * Bend [DropDownPreference] to support
32  * [Simple Menus](https://material.google.com/components/menus.html#menus-behavior).
33  */
34 class SimpleMenuPreference(
35     context: Context?,
36     attrs: AttributeSet?,
37     defStyleAttr: Int,
38     defStyleRes: Int
39 ) : DropDownPreference(context!!, attrs, defStyleAttr, defStyleRes) {
40     private lateinit var mAdapter: SimpleMenuAdapter
41 
42     constructor(context: Context?) : this(context, null) {
43     }
44 
45     constructor(context: Context?, attrs: AttributeSet?) :
46             this(context, attrs, R.attr.dropdownPreferenceStyle) {
47     }
48 
49     constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) :
50             this(context, attrs, defStyle, 0) {
51     }
52 
createAdapternull53     override fun createAdapter(): ArrayAdapter<CharSequence?> {
54         mAdapter = SimpleMenuAdapter(getContext(), R.layout.simple_menu_dropdown_item)
55         return mAdapter
56     }
57 
setSummarynull58     override fun setSummary(summary: CharSequence?) {
59         val entries: Array<CharSequence> = getEntries()
60         val index = Utils.indexOf(entries, summary!!)
61         require(index != -1) { "Illegal Summary" }
62         val lastSelectedOriginalPosition = mAdapter.lastSelectedOriginalPosition
63         mAdapter.setSelectedPosition(index)
64         setSelectedPosition(entries, lastSelectedOriginalPosition, index)
65         setSelectedPosition(getEntryValues(), lastSelectedOriginalPosition, index)
66         super.setSummary(summary)
67     }
68 
69     private class SimpleMenuAdapter internal constructor(context: Context, resource: Int) :
70             ArrayAdapter<CharSequence?>(context, resource) {
71 
72         /** The original position of the last selected element  */
73         var lastSelectedOriginalPosition = 0
74             private set
75 
restoreOriginalOrdernull76         private fun restoreOriginalOrder() {
77             val item: CharSequence? = getItem(0)
78             remove(item)
79             insert(item, lastSelectedOriginalPosition)
80         }
81 
swapSelectedToFrontnull82         private fun swapSelectedToFront(position: Int) {
83             val item: CharSequence? = getItem(position)
84             remove(item)
85             insert(item, 0)
86             lastSelectedOriginalPosition = position
87         }
88 
setSelectedPositionnull89         fun setSelectedPosition(position: Int) {
90             setNotifyOnChange(false)
91             val item: CharSequence? = getItem(position)
92             restoreOriginalOrder()
93             val originalPosition: Int = getPosition(item)
94             swapSelectedToFront(originalPosition)
95             notifyDataSetChanged()
96         }
97 
getDropDownViewnull98         override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
99             val view: View = super.getDropDownView(position, convertView, parent)
100             if (position == 0) {
101                 view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.white_08p))
102             } else {
103                 view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.transparent))
104             }
105             return view
106         }
107     }
108 
109     companion object {
restoreOriginalOrdernull110         private fun restoreOriginalOrder(
111             array: Array<CharSequence>,
112             lastSelectedOriginalPosition: Int
113         ) {
114             val item = array[0]
115             System.arraycopy(array, 1, array, 0, lastSelectedOriginalPosition)
116             array[lastSelectedOriginalPosition] = item
117         }
118 
swapSelectedToFrontnull119         private fun swapSelectedToFront(array: Array<CharSequence>, position: Int) {
120             val item = array[position]
121             System.arraycopy(array, 0, array, 1, position)
122             array[0] = item
123         }
124 
setSelectedPositionnull125         private fun setSelectedPosition(
126             array: Array<CharSequence>,
127             lastSelectedOriginalPosition: Int,
128             position: Int
129         ) {
130             val item = array[position]
131             restoreOriginalOrder(array, lastSelectedOriginalPosition)
132             val originalPosition = Utils.indexOf(array, item)
133             swapSelectedToFront(array, originalPosition)
134         }
135     }
136 }
137