Я делаю лаунчер для своего телефона, и мне нужно отсортировать приложения по алфавиту.
Appslist = ArrayList<AppInfo>()
val i = Intent(Intent.ACTION_MAIN, null)
i.addCategory(Intent.CATEGORY_LAUNCHER)
val allApps = this.packageManager.queryIntentActivities(i, 0)
for (ri in allApps) {
val app = AppInfo()
app.label = ri.loadLabel(this.packageManager)
app.packageName = ri.activityInfo.packageName
app.icon = ri.activityInfo.loadIcon(this.packageManager)
if (app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){
if (app.packageName != "com.david.launcher" ){
Appslist.add(app)
}
}
if (searchWord == ""){
if (app.packageName != "com.david.launcher"){
Appslist.add(app)
}
}
}
Вот мой тип списка (я действительно не знаю, называется ли он типом списка, но надеюсь, вы поймете):
public class AppInfo {
internal var label: CharSequence? = null
internal var packageName: CharSequence? = null
internal var icon: Drawable? = null
internal var isInFav: Boolean? = false
@pratikvekariya, ваш комментарий неверен, это список классов, которые не реализуют Comparable и, следовательно, не имеют естественного порядка, ваш метод не работает, и, кроме того, он не является идиоматическим для Kotlin.
Дэвид, есть ответ на ваш вопрос или вы ищете что-то еще?
Да, это. (:





Вы можете сделать это с помощью Collections.sort() и либо специальной реализации Comparator<AppInfo>, которая работает с AppInfo.label, либо заставить класс AppInfo реализовать интерфейс Comparable и реализовать метод compareTo таким образом, чтобы просто сравнивать поля меток.
Этот ответ неполный, потому что это более сложный вопрос. Во-первых, типы данных, доступные для сортировки, не подлежат сортировке (CharSequence), и это не идиоматический тип Kotlin: создавать Comparator только для одноразовой сортировки или снова добавлять Comparable в класс для одноразовой сортировки. Также необходимо учитывать нулевую обработку, поскольку все типы в классе допускают нулевое значение.
Идиоматический способ - использовать метод расширения sortedBy для List, если вы хотите отсортировать по копии списка. Или используйте расширение sortBy на MutableList, если вы хотите выполнить сортировку на месте без копии. ArrayList будет работать как со списком любого типа.
// Sort a readonly list into a copy of the list
val appsList: List<AppInfo> = ...
val sortedAppsList = appsList.sortedBy { it.label?.toString() }
против:
// Sort a mutable list in-place
val appsList: MutableList<AppInfo> = ...
appList.sortBy { it.label?.toString() }
и если вы держите как ArrayList, то это то же самое, но не идиоматично, иметь ссылку непосредственно на этот конкретный тип.
// Sort an ArrayList list into a copy of the list
val appsList: ArrayList<AppInfo> = ... // ALERT! not idiomatic
val sortedAppsList = appsList.sortedBy { it.label?.toString() }
// or if you want, feel free to sort in-place
appsList.sortBy { it.label?.toString() }
Обратите внимание на toString() на элементе label: CharSequence. Вы должны быть осторожны при сортировке ссылки типа CharSequence, поскольку она не определена, каково ее поведение при сортировке (см .: https://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html)
This interface does not refine the general contracts of the equals and hashCode methods. The result of comparing two objects that implement CharSequence is therefore, in general, undefined.
Если CharSequence уже является String (скорее всего, так), то вызов toString() не причинит вреда, поскольку он просто возвращает себя.
Также имейте в виду, что CharSequence, допускающий значение NULL, также должен обрабатываться, и вам нужно решить, где вы хотите использовать NULL: в начале или в конце списка. Я думаю, что по умолчанию они выходят на старт.
Другие примечания о вашем коде в вопросе:
Используйте интерфейс List или MutableList вместо конкретного класса для ссылки на тип и используйте методы из Kotlin stdlib для выполнения действий со списком. Также используйте val вместо var для ссылок, которые не изменятся (это означает, что он всегда будет указывать на один и тот же список независимо от того, может ли содержимое списка измениться).
У вас есть большое заявление о if, которое можно значительно сократить, начиная с ...
if (app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){
if (app.packageName != "com.david.launcher" ){
Appslist.add(app)
}
}
if (searchWord == ""){
if (app.packageName != "com.david.launcher"){
Appslist.add(app)
}
}
проще:
if (app.packageName != "com.david.launcher" &&
(searchWord.isBlank() ||
app.label?.startsWith(searchWord, ignoreCase = true) == true)) {
appsList.add(app)
}
Вам следует просмотреть стандартную библиотеку, чтобы получить представление о том, что доступно, чтобы вы могли расширить свой инструментарий в будущем.
Спасибо! Это действительно помогает, когда я нахожу что-то в списке.
class CustomClass {
var id: String = ""
var name: String = ""
}
fun sortAlphabetically(arrayList: ArrayList< CustomClass >): ArrayList< CustomClass >{
var returnList: ArrayList< CustomClass > = arrayListOf()
var list = arrayList as MutableList< CustomClass >
list.sortWith(Comparator { o1: CustomClass, o2: CustomClass ->
o1.name.compareTo(o2.name)
})
returnList = list as ArrayList< CustomClass >
return returnList
}
используйте Collections.sort (your_list), это даст вам отсортированный список