-
-
Notifications
You must be signed in to change notification settings - Fork 493
/
SortActivity.kt
239 lines (207 loc) · 8.68 KB
/
SortActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package com.mikepenz.fastadapter.app
import android.graphics.Color
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.annotation.IntDef
import androidx.annotation.IntRange
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IAdapter
import com.mikepenz.fastadapter.adapters.ItemAdapter
import com.mikepenz.fastadapter.app.databinding.ActivitySampleBinding
import com.mikepenz.fastadapter.app.items.SimpleItem
import com.mikepenz.fastadapter.select.SelectExtension
import com.mikepenz.fastadapter.select.getSelectExtension
import com.mikepenz.fastadapter.utils.ComparableItemListImpl
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.materialdesigniconic.MaterialDesignIconic
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.colorInt
import java.io.Serializable
import java.util.*
/**
* An Activity which showcases the sort feature of the library.
*
* @author Ruben Gees
*/
class SortActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleBinding
//save our FastAdapter
private lateinit var fastAdapter: FastAdapter<SimpleItem>
private lateinit var itemAdapter: ItemAdapter<SimpleItem>
private lateinit var itemListImpl: ComparableItemListImpl<SimpleItem>
private lateinit var selectExtension: SelectExtension<SimpleItem>
@SortingStrategy
private var sortingStrategy: Int = 0
/**
* Returns the appropriate Comparator for the current sorting strategy or null if no strategy is
* set. (SORT_NONE)
*
* @return The comparator or null.
*/
private val comparator: Comparator<SimpleItem>?
get() {
when (sortingStrategy) {
SORT_ASCENDING -> return AlphabetComparatorAscending()
SORT_DESCENDING -> return AlphabetComparatorDescending()
SORT_NONE -> return null
}
throw RuntimeException("This sortingStrategy is not supported.")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
//create our FastAdapter which will manage everything
itemListImpl = ComparableItemListImpl(comparator)
itemAdapter = ItemAdapter(itemListImpl)
fastAdapter = FastAdapter.with(itemAdapter)
selectExtension = fastAdapter.getSelectExtension()
selectExtension.isSelectable = true
//configure our fastAdapter
fastAdapter.onClickListener = { _: View?, _: IAdapter<SimpleItem>, item: SimpleItem, _: Int ->
Toast.makeText(this@SortActivity, item.name?.getText(this@SortActivity), Toast.LENGTH_LONG).show()
false
}
//get our recyclerView and do basic setup
binding.rv.layoutManager = LinearLayoutManager(this)
binding.rv.itemAnimator = DefaultItemAnimator()
binding.rv.adapter = fastAdapter
sortingStrategy = if (savedInstanceState != null) {
//Retrieve the previous sorting strategy from the instance state
toSortingStrategy(savedInstanceState.getInt("sorting_strategy"))
} else {
//Set the default so
SORT_NONE
}
//initial filling of the list
itemAdapter.setNewList(generateUnsortedList())
//restore selections (this has to be done after the items were added
fastAdapter.withSavedInstanceState(savedInstanceState)
//set the back arrow in the toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(false)
}
@SortingStrategy
internal fun toSortingStrategy(`val`: Int): Int {
return `val`
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the adapter to the bundle
outState = fastAdapter.saveInstanceState(outState)
//We need to persist our sorting strategy between orientation changes
outState.putInt("sorting_strategy", sortingStrategy)
super.onSaveInstanceState(outState)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.sort, menu)
menu.findItem(R.id.item_sort_random).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_wrap_text).apply { colorInt = Color.BLACK; actionBar() }
menu.findItem(R.id.item_sort_asc).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_sort_asc).apply { colorInt = Color.BLACK; actionBar() }
menu.findItem(R.id.item_sort_desc).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_sort_desc).apply { colorInt = Color.BLACK; actionBar() }
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the menu item click
when (item.itemId) {
R.id.item_sort_random -> {
//Set the new sorting strategy
sortingStrategy = SORT_NONE
//randomize the items
itemAdapter.adapterItems.shuffle()
fastAdapter.notifyDataSetChanged()
return true
}
R.id.item_sort_asc -> {
//Set the new sorting strategy
sortingStrategy = SORT_ASCENDING
//Set the new comparator to the list
itemListImpl.withComparator(comparator)
return true
}
R.id.item_sort_desc -> {
//Set the new sorting strategy
sortingStrategy = SORT_DESCENDING
//Set the new comparator to the list
itemListImpl.withComparator(comparator)
return true
}
android.R.id.home -> {
Toast.makeText(applicationContext, "selections = " + selectExtension.selections, Toast.LENGTH_LONG).show()
onBackPressed()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
/**
* Generates a simple list consisting of the letters of the alphabet, unordered on purpose.
*
* @return The new list.
*/
private fun generateUnsortedList(): List<SimpleItem> {
val result = ArrayList<SimpleItem>(26)
for (i in 0..25) {
result.add(makeItem(i))
}
result.shuffle()
return result
}
/**
* Build a simple item with one letter of the alphabet.
*
* @param position The position of the letter in the alphabet.
* @return The new item.
*/
private fun makeItem(@IntRange(from = 0, to = 25) _position: Int): SimpleItem {
var position = _position
val result = SimpleItem()
result.withName(ALPHABET[position])
position++
var description = "The $position"
description += if (position == 1 || position == 21) {
"st"
} else if (position == 2 || position == 22) {
"nd"
} else if (position == 3 || position == 23) {
"rd"
} else {
"th"
}
return result.withDescription("$description letter in the alphabet")
}
@Retention(AnnotationRetention.SOURCE)
@IntDef(SORT_NONE, SORT_ASCENDING, SORT_DESCENDING)
annotation class SortingStrategy
/**
* A simple Comparator to sort the items ascending.
*/
private inner class AlphabetComparatorAscending : Comparator<SimpleItem>, Serializable {
override fun compare(lhs: SimpleItem, rhs: SimpleItem): Int {
return lhs.name?.textString.toString().compareTo(rhs.name?.textString.toString())
}
}
/**
* A simple Comparator to sort the items descending.
*/
private inner class AlphabetComparatorDescending : Comparator<SimpleItem>, Serializable {
override fun compare(lhs: SimpleItem, rhs: SimpleItem): Int {
return rhs.name?.textString.toString().compareTo(lhs.name?.textString.toString())
}
}
companion object {
private const val SORT_ASCENDING = 0
private const val SORT_DESCENDING = 1
private const val SORT_NONE = -1
private val ALPHABET = arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
}
}