Skip to content

Instantly share code, notes, and snippets.

@PaulWoitaschek
Last active July 28, 2017 06:43
Show Gist options
  • Save PaulWoitaschek/ea893f26dd1fe1b30c0fcc286685ea00 to your computer and use it in GitHub Desktop.
Save PaulWoitaschek/ea893f26dd1fe1b30c0fcc286685ea00 to your computer and use it in GitHub Desktop.
Controller Argument Delegation. An extensible mechanism for seriaizing values to the Controllers bundle.
/**
* An abstract argument delegate that uses the property to infer the key name for the bundle.
*/
abstract class ControllerArgumentDelegate<T : Any> : ReadWriteProperty<Controller, T> {
private var value: T? = null
override final fun getValue(thisRef: Controller, property: KProperty<*>): T {
if (value == null) {
val key = property.name
value = fromBundle(thisRef.args, key)
}
return value ?: throw IllegalStateException("Property ${property.name} could not be read")
}
override final fun setValue(thisRef: Controller, property: KProperty<*>, value: T) {
val bundle = thisRef.args
val key = property.name
toBundle(bundle, key, value)
}
abstract fun toBundle(bundle: Bundle, key: String, value: T)
abstract fun fromBundle(bundle: Bundle, key: String): T
}
class EnumArgumentDelegate<E : Enum<E>>(private val clazz: Class<E>) : ControllerArgumentDelegate<E>() {
override fun toBundle(bundle: Bundle, key: String, value: E) {
bundle.putString(key, value.name)
}
override fun fromBundle(bundle: Bundle, key: String): E {
val stringValue = bundle.getString(key)
return java.lang.Enum.valueOf(clazz, stringValue)
}
}
inline fun <reified E : Enum<E>> enumArgumentDelegate() = EnumArgumentDelegate(E::class.java)
class StringArgumentDelegate : ControllerArgumentDelegate<String>() {
override fun toBundle(bundle: Bundle, key: String, value: String) {
bundle.putString(key, value)
}
override fun fromBundle(bundle: Bundle, key: String): String = bundle.getString(key)
}
@PaulWoitaschek
Copy link
Author

Sample:

class Sample() : Controller() {

  private var heightUnit: HeightUnit by enumArgumentDelegate()
  private var name by StringArgumentDelegate()

  constructor(heightUnit: HeightUnit, name: String) : this() {
    this.heightUnit = heightUnit
    this.name = name
  }

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup) = TextView(activity!!)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment