Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Leaking/2591eceff9109324920d66d3c21bd17e to your computer and use it in GitHub Desktop.
Save Leaking/2591eceff9109324920d66d3c21bd17e to your computer and use it in GitHub Desktop.
Fragment arguments without hassle !
package be.brol
import android.os.Binder
import android.os.Bundle
import android.support.v4.app.BundleCompat
import android.support.v4.app.Fragment
/**
* Eases the Fragment.newInstance ceremony by marking the fragment's args with this delegate
* Just write the property in newInstance and read it like any other property after the fragment has been created
*
* Inspired by Adam Powell, he mentioned it during his IO/17 talk about Kotlin
*/
class FragmentArgumentDelegate<T : Any> : kotlin.properties.ReadWriteProperty<Fragment, T> {
var value: T? = null
override operator fun getValue(thisRef: android.support.v4.app.Fragment, property: kotlin.reflect.KProperty<*>): T {
if (value == null) {
val args = thisRef.arguments ?: throw IllegalStateException("Cannot read property ${property.name} if no arguments have been set")
@Suppress("UNCHECKED_CAST")
value = args.get(property.name) as T
}
return value ?: throw IllegalStateException("Property ${property.name} could not be read")
}
override operator fun setValue(thisRef: android.support.v4.app.Fragment, property: kotlin.reflect.KProperty<*>, value: T) {
if (thisRef.arguments == null) thisRef.arguments = android.os.Bundle()
val args = thisRef.arguments
val key = property.name
when (value) {
is String -> args.putString(key, value)
is Int -> args.putInt(key, value)
is Short -> args.putShort(key, value)
is Long -> args.putLong(key, value)
is Byte -> args.putByte(key, value)
is ByteArray -> args.putByteArray(key, value)
is Char -> args.putChar(key, value)
is CharArray -> args.putCharArray(key, value)
is CharSequence -> args.putCharSequence(key, value)
is Float -> args.putFloat(key, value)
is Bundle -> args.putBundle(key, value)
is Binder -> BundleCompat.putBinder(args, key, value)
is android.os.Parcelable -> args.putParcelable(key, value)
is java.io.Serializable -> args.putSerializable(key, value)
else -> throw IllegalStateException("Type ${value.javaClass.canonicalName} of property ${property.name} is not supported")
}
}
}
package be.brol
import android.os.Bundle
import android.support.v4.app.Fragment
import android.widget.Toast
/**
* Example usage of FragmentArgumentDelegate
*/
class WeatherCityFragment : Fragment() {
private var cityId by FragmentArgumentDelegate<String>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Toast.makeText(activity, cityId, Toast.LENGTH_SHORT).show()
}
companion object {
fun newInstance(cityId: String) = WeatherCityFragment().apply {
this.cityId = cityId
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment