Skip to content

Commit 695c4f5

Browse files
committed
Fixed NPE in IconDialog when icon has no category
1 parent 4752dd4 commit 695c4f5

File tree

5 files changed

+20
-9
lines changed

5 files changed

+20
-9
lines changed

lib/src/main/kotlin/com/maltaisn/icondialog/IconDialogPresenter.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.maltaisn.icondialog
1818

1919
import android.os.Bundle
20+
import androidx.recyclerview.widget.RecyclerView
2021
import com.maltaisn.icondialog.IconDialog.*
2122
import com.maltaisn.icondialog.IconDialogContract.View
2223
import com.maltaisn.icondialog.data.Category
@@ -231,7 +232,7 @@ internal class IconDialogPresenter : IconDialogContract.Presenter {
231232
}
232233
i--
233234
}
234-
return -1
235+
return RecyclerView.NO_POSITION
235236
}
236237

237238
override fun onIconItemClicked(pos: Int) {
@@ -349,7 +350,7 @@ internal class IconDialogPresenter : IconDialogContract.Presenter {
349350
while (i < listItems.size) {
350351
val prevId = (listItems.getOrNull(i - 1) as IconItem?)?.icon?.categoryId
351352
val currId = (listItems[i] as IconItem).icon.categoryId
352-
if (currId != prevId) {
353+
if (currId != prevId && currId != Icon.NO_CATEGORY) {
353354
listItems.add(i, HeaderItem(iconPack.getCategory(currId)!!))
354355
i++
355356
}

lib/src/main/kotlin/com/maltaisn/icondialog/StickyHeaderDecoration.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ internal class StickyHeaderDecoration(
5050
val topChildPosition = parent.getChildAdapterPosition(topChild)
5151
if (topChildPosition == RecyclerView.NO_POSITION) return // Again, empty list.
5252

53-
val viewHolder = setHeaderViewHolder(topChildPosition, parent)
53+
val viewHolder = setHeaderViewHolder(topChildPosition, parent) ?: return
5454
val childInContact = getChildInContact(parent, viewHolder.itemView)
5555
if (childInContact != null) {
5656
val childInContactPos = parent.getChildAdapterPosition(childInContact)
@@ -84,7 +84,7 @@ internal class StickyHeaderDecoration(
8484

8585
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) = Unit
8686

87-
private fun setHeaderViewHolder(position: Int, parent: RecyclerView): RecyclerView.ViewHolder {
87+
private fun setHeaderViewHolder(position: Int, parent: RecyclerView): RecyclerView.ViewHolder? {
8888
var viewHolder = headerViewHolder
8989
if (viewHolder == null) {
9090
// Header view holder was not yet created
@@ -94,6 +94,10 @@ internal class StickyHeaderDecoration(
9494

9595
// Bind sticky header view holder data
9696
val headerPos = callback.getHeaderPositionForItem(position)
97+
if (headerPos == RecyclerView.NO_POSITION) {
98+
return null
99+
}
100+
97101
callback.onBindViewHolder(viewHolder, headerPos)
98102
if (stickyHeaderHeight == -1) {
99103
// Measure parent RecyclerView

lib/src/main/kotlin/com/maltaisn/icondialog/data/Icon.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
package com.maltaisn.icondialog.data
1818

1919
import android.graphics.drawable.Drawable
20+
import com.maltaisn.icondialog.data.Icon.Companion.NO_CATEGORY
2021
import com.maltaisn.icondialog.pack.IconDrawableLoader
2122

2223

2324
/**
2425
* An icon with an unique [id], a [categoryId], a list of [tags] names and SVG [pathData].
25-
* [categoryId] can be `-1` if the icon has no category.
26+
* [categoryId] can be [NO_CATEGORY] if the icon has no category.
2627
* Icon also have a [width] and a [height] in pixels.
2728
*/
2829
data class Icon(val id: Int,
@@ -45,4 +46,9 @@ data class Icon(val id: Int,
4546
internal set
4647
get() = field?.constantState?.newDrawable()
4748

49+
50+
companion object {
51+
const val NO_CATEGORY = -1
52+
}
53+
4854
}

lib/src/main/kotlin/com/maltaisn/icondialog/filter/IconFilter.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ interface IconFilter : Comparator<Icon>, Parcelable {
3333
fun queryIcons(pack: IconPack, query: String? = null): MutableList<Icon>
3434

3535
/**
36-
* Compare [icon1] and [icon2], two icons which are of the same category.
36+
* Compare [icon1] and [icon2], two icons in the same category.
3737
*/
3838
override fun compare(icon1: Icon, icon2: Icon): Int
3939

lib/src/main/kotlin/com/maltaisn/icondialog/pack/IconPackLoader.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class IconPackLoader(context: Context) {
8484
private fun loadIcons(pack: IconPack, @XmlRes iconsXml: Int) {
8585
val newIcons = mutableMapOf<Int, Icon>()
8686
val newCategories = mutableMapOf<Int, Category>()
87-
var categoryId: Int = -1
87+
var categoryId = Icon.NO_CATEGORY
8888

8989
var documentStarted = false
9090
var iconStarted = false
@@ -108,7 +108,7 @@ class IconPackLoader(context: Context) {
108108

109109
when (element) {
110110
XML_TAG_CATEGORY -> {
111-
if (categoryId != -1) parseError("Nested category element is not allowed.")
111+
if (categoryId != Icon.NO_CATEGORY) parseError("Nested category element is not allowed.")
112112
val category = parseCategory(parser, pack)
113113
categoryId = category.id
114114
if (categoryId in newCategories) {
@@ -130,7 +130,7 @@ class IconPackLoader(context: Context) {
130130

131131
} else if (eventType == XmlPullParser.END_TAG) {
132132
if (element == XML_TAG_CATEGORY) {
133-
categoryId = -1
133+
categoryId = Icon.NO_CATEGORY
134134
} else if (element == XML_TAG_ICON) {
135135
iconStarted = false
136136
}

0 commit comments

Comments
 (0)