LouisCAD / Splitties

A collection of hand-crafted extensions for your Kotlin projects.
https://splitties.louiscad.com
Apache License 2.0
2.53k stars 159 forks source link

Spinner SafeSelection #238

Closed vincent-paing closed 4 years ago

vincent-paing commented 4 years ago

I just found out about this library and wanted to contribute with an extension function I've been using for Spinners.

Problem : Spinners has setSelection function that can throw IndexOutOfBounds when you select an item that doesn't exist in that index. Sometimes, an edge case could happen when you just invalidate the data in adapter at the same time, your spinner setSelection has been invoked, which cause the app to crash.

So, I come up with this function

/**
 * Safely select Spinner and invoke [doOnError] function when an error is thrown during selection
 *
 * @param position Position to be selected
 * @param doOnError A function that is invoked when an error is thrown, by default this log the exception 
 * @param doAfterSelect A optional function that can be executed if the selection is successfully completed
 */
fun Spinner.safeSelection(
  position: Int,
  doOnError: ((Exception) -> (Unit)) = { error ->
    Log.e("SpinnerExtensions", Log.getStackTraceString(error))
  },
  doAfterSelect: ((Int) -> (Unit)) = { _ ->
    //Do Nothing
  }
) {
  try {
    setSelection(position)
    doAfterSelect(position)
  } catch (e: Exception) {
    doOnError.invoke(e)
  }

}

If this can be added, I'm more than happy to submit a PR

LouisCAD commented 4 years ago

This looks like a race condition that can be fixed by ensuring operations are done sequentially (coroutines can help here).

I prefer to not add that extension to Splitties, mainly because it's more a band-aid solution that doesn't solve the root problem.