Last active
March 21, 2018 04:57
-
-
Save scottroemeschke/3e97fa6428656e52cc923f7b8faf7582 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BindView<V: View>(@IdRes val id: Int): ReadOnlyProperty<Any, V> { | |
private var view: V? = null | |
override fun getValue(thisRef: Any, property: KProperty<*>): V { | |
return view ?: getViewInitial(thisRef) | |
} | |
private fun getViewInitial(thisRef: Any): V { | |
val foundView: V = when (thisRef) { | |
is AppCompatActivity -> thisRef.findViewById(id) ?: throw Exception("view not found") | |
is Fragment -> { | |
val fragmentView = thisRef.view ?: throw Exception("fragment view is currently null.") | |
fragmentView.findViewById(id) ?: throw Exception("view not found") | |
} | |
is ViewGroup -> thisRef.findViewById(id) ?: throw Exception("view not found") | |
is RecyclerView.ViewHolder -> thisRef.itemView.findViewById(id) ?: throw Exception("view not found") | |
else -> throw Exception("bind view property delegate used in unsupported class ${thisRef.javaClass.simpleName}") | |
} | |
view = foundView | |
return foundView | |
} | |
} | |
class BindNullableView<V: View>(@IdRes val id: Int): ReadOnlyProperty<Any, V?> { | |
private var view: V? = null | |
private var checkedForView = false | |
override fun getValue(thisRef: Any, property: KProperty<*>): V? { | |
return when (checkedForView) { | |
true -> view | |
else -> getViewInitial(thisRef) | |
} | |
} | |
private fun getViewInitial(thisRef: Any): V? { | |
val foundView: V = when (thisRef) { | |
is AppCompatActivity -> thisRef.findViewById(id) | |
is Fragment -> { | |
val fragmentView = thisRef.view ?: throw Exception("fragment view is currently null.") | |
fragmentView.findViewById(id) | |
} | |
is ViewGroup -> thisRef.findViewById(id) | |
is RecyclerView.ViewHolder -> thisRef.itemView.findViewById(id) | |
else -> throw Exception("bind view property delegate used in unsupported class ${thisRef.javaClass.simpleName}") | |
} | |
view = foundView | |
checkedForView = true | |
return foundView | |
} | |
} | |
//Examples in use | |
class SomeFragment: Fragment() { | |
val someButton by BindView<Button>(R.id.nextButton) | |
val someTextView by BindNullableView<TextView>(R.id.text_accepted_offer_from) | |
} | |
class SomeViewHolder(itemView): RecyclerView.ViewHolder(itemView) { | |
val someCoolView by BindView<View>(R.id.view_empty) | |
val someOtherViewWhichMightBeNull by BindNullableView<LinearLayout>(R.id.vehicle_headline) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment