@@ -13,22 +13,33 @@ import android.graphics.PorterDuff
13
13
import android.graphics.PorterDuffColorFilter
14
14
import android.support.v4.content.ContextCompat
15
15
import android.util.DisplayMetrics
16
-
16
+ import android.view.LayoutInflater
17
+
18
+ /*
19
+ * Converts a String array via an @array resource into selectable/deselectable views that act as a
20
+ * CheckBox. Selected views are returned via a String ArrayList, either via the listener or public
21
+ * function.
22
+ * @param Context
23
+ * @param AttributeSet
24
+ */
17
25
class CheckBoxTextViews (context : Context , attrs : AttributeSet ): LinearLayout(context, attrs),
18
26
View .OnClickListener {
19
27
20
28
init {
21
- init (context, attrs)
29
+ init (attrs)
22
30
}
23
31
24
- private var _flexbox : FlexboxLayout ? = null
32
+ private var _flexbox : FlexboxLayout ? = null // CheckBox item host layout. Flexbox is set up
33
+ // so that items flow to next line and are
34
+ // centered
25
35
26
- private var _defaultBackgroundColour = 0
27
- private var _defaultTextColour = 0
28
- private var _selectedBackgroundColour = 0
29
- private var _selectedTextColour = 0
36
+ private var _defaultBackgroundColour = 0 // Deselected CheckBox item background colour
37
+ private var _defaultTextColour = 0 // Deselected CheckBox item text colour
38
+ private var _selectedBackgroundColour = 0 // Selected CheckBox item background colour
39
+ private var _selectedTextColour = 0 // Selected CheckBox item text clour
30
40
31
- private var _defaultSelected = false
41
+ private var _defaultSelected = false // Whether or not the CheckBox items are
42
+ // initially selected
32
43
33
44
private var _selectedItems : ArrayList <String >? = null
34
45
private var _selectedItemListener : CheckBoxTextViewsListener ? = null
@@ -37,17 +48,26 @@ class CheckBoxTextViews(context: Context, attrs: AttributeSet): LinearLayout(con
37
48
selectView(v)
38
49
}
39
50
40
- private fun init (context : Context , attrs : AttributeSet ){
41
- val root = inflate(context, R .layout.checkbox_item_host, this )
42
- _flexbox = root.rootFlexboxLayout
51
+ /*
52
+ * Inflate and retrieve the CheckBox item host layout. Handle attribute resources.
53
+ * @param AttributeSet passed to HandleAttributes
54
+ */
55
+ private fun init (attrs : AttributeSet ){
56
+ val root = LayoutInflater .from(context).inflate(R .layout.checkbox_item_host,
57
+ this , true )
43
58
44
- _selectedItems = ArrayList ()
59
+ _flexbox = root.rootFlexboxLayout
60
+ _selectedItems = ArrayList ()
45
61
46
- handleDefaultAttributes(context )
47
- handleAttributes(context, attrs)
62
+ handleDefaultAttributes()
63
+ handleAttributes(attrs)
48
64
}
49
65
50
- private fun handleDefaultAttributes (context : Context ){
66
+ /*
67
+ * Set attributes to initial default values. These are the values that are used if none are
68
+ * supplied via the View.
69
+ */
70
+ private fun handleDefaultAttributes (){
51
71
val themeAttrs = intArrayOf(R .attr.colorAccent)
52
72
val ta = context.theme.obtainStyledAttributes(themeAttrs)
53
73
@@ -59,7 +79,13 @@ class CheckBoxTextViews(context: Context, attrs: AttributeSet): LinearLayout(con
59
79
ta.recycle()
60
80
}
61
81
62
- private fun handleAttributes (context : Context , attrs : AttributeSet ){
82
+ /*
83
+ * Attempt to obtain the supplied resources via the View. The resources that the user can
84
+ * provide are the CheckBox items deselected/selected background colour and text colour, whether
85
+ * the items are initially selected and the String array to create the CheckBox items from.
86
+ * @param AttributeSet used to obtain the styleable attributes from the View
87
+ */
88
+ private fun handleAttributes (attrs : AttributeSet ){
63
89
val ta = context.theme.obtainStyledAttributes(attrs, R .styleable.CheckBoxTextViews ,
64
90
0 , 0 )
65
91
@@ -74,6 +100,7 @@ class CheckBoxTextViews(context: Context, attrs: AttributeSet): LinearLayout(con
74
100
_defaultSelected = ta.getBoolean(
75
101
R .styleable.CheckBoxTextViews_cbtv_selected , false )
76
102
103
+ // Retrieve the items via the provided String array and create the CheckBox items
77
104
val itemsId = ta.getResourceId(R .styleable.CheckBoxTextViews_cbtv_items , 0 )
78
105
if (itemsId != 0 ){
79
106
val items: Array <String > = resources.getStringArray(itemsId)
@@ -83,46 +110,54 @@ class CheckBoxTextViews(context: Context, attrs: AttributeSet): LinearLayout(con
83
110
}
84
111
}
85
112
113
+ /*
114
+ * A CheckBox item is a rounded rectangle view with centered text, that is selectable. Inflate
115
+ * the CheckBox item layout and set the title and and root Views corresponding to the String and
116
+ * attribute resources.
117
+ * @param String the CheckBox item text
118
+ */
86
119
private fun createCheckBoxItem (item : String ){
87
- val checkBoxItem: View = inflate(context, R .layout.checkbox_item, null )
120
+ val checkBoxItem: View = LayoutInflater .from(context).inflate(R .layout.checkbox_item,
121
+ _flexbox , false )
122
+
88
123
val root: ClipView = checkBoxItem.rootClipView
89
124
val title: TextView = checkBoxItem.itemTextView
90
125
91
126
title.text = item
92
127
title.setTextColor(_defaultTextColour )
93
128
94
129
setBackgroundColour(root, _defaultBackgroundColour )
95
-
96
- val layoutParams = FlexboxLayout .LayoutParams (FlexboxLayout .LayoutParams .WRAP_CONTENT ,
97
- FlexboxLayout .LayoutParams .WRAP_CONTENT )
98
-
99
- layoutParams.setMargins(dpToPx(8f ), dpToPx(8f ), dpToPx(8f ), 0 )
100
- checkBoxItem.layoutParams = layoutParams
101
130
checkBoxItem.setOnClickListener(this )
102
131
132
+ // During inflation, 'attachToRoot' can be specified, however, Views need to be added to the
133
+ // FlexBox individually so that the specified rules are used (flex to new line, centered)
103
134
_flexbox !! .addView(checkBoxItem)
104
135
136
+ // Users can specify whether or not the CheckBox items should initially be selected
105
137
if (_defaultSelected ){
106
138
selectView(checkBoxItem)
107
139
}
108
140
}
109
141
110
- private fun setBackgroundColour ( view : View , colour : Int ){
111
- view.background.colorFilter = PorterDuffColorFilter (colour,
112
- PorterDuff . Mode . SRC_IN )
113
- }
114
-
142
+ /*
143
+ * Sets the CheckBox items tag to reflect whether or not it has been selected. Set the CheckBox
144
+ * items background colour and text colour corresponding to its selection status.
145
+ * @param View? the CheckBox items root layout
146
+ */
115
147
private fun selectView (v : View ? ){
116
148
// Update whether or not the item has been selected via the tag
117
149
if (v!! .tag == null ){
150
+ // If first time setting the tag, it must have been selected, so it must be true
118
151
v.tag = true
119
152
} else {
120
153
v.tag = ! (v.tag as Boolean )
121
154
}
122
155
123
- val title = v.itemTextView
124
- val root = v.rootClipView
156
+ val title = v.itemTextView // Used to change text colour
157
+ val root = v.rootClipView // Used to change background colour
125
158
159
+ // Update text and background colour of the CheckBox item depending on whether or not it has
160
+ // been selected
126
161
if (v.tag as Boolean ){
127
162
title.setTextColor(_selectedTextColour )
128
163
setBackgroundColour(root, _selectedBackgroundColour )
@@ -135,18 +170,30 @@ class CheckBoxTextViews(context: Context, attrs: AttributeSet): LinearLayout(con
135
170
_selectedItems !! .remove(title.text.toString())
136
171
}
137
172
173
+ // Call the listener
138
174
_selectedItemListener ?.onItemSelected(_selectedItems !! )
139
175
}
140
176
177
+ // HELPERS
178
+ // //////////////////////////////////////////////////////////////////////////////////////////////
179
+
180
+ private fun setBackgroundColour (view : View , colour : Int ){
181
+ view.background.colorFilter = PorterDuffColorFilter (colour,
182
+ PorterDuff .Mode .SRC_IN )
183
+ }
184
+
185
+ private fun dpToPx (dp : Float ): Int {
186
+ return Math .round(dp * (Resources .getSystem().displayMetrics.xdpi / DisplayMetrics .DENSITY_DEFAULT ))
187
+ }
188
+
189
+ // ACCESSORS
190
+ // //////////////////////////////////////////////////////////////////////////////////////////////
191
+
141
192
fun getSelectedItems (): ArrayList <String > {
142
193
return _selectedItems !!
143
194
}
144
195
145
196
fun setSelectedItemListener (listener : CheckBoxTextViewsListener ){
146
197
_selectedItemListener = listener
147
198
}
148
-
149
- private fun dpToPx (dp : Float ): Int {
150
- return Math .round(dp * (Resources .getSystem().displayMetrics.xdpi / DisplayMetrics .DENSITY_DEFAULT ))
151
- }
152
199
}
0 commit comments