Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Support binding from custom classes #74

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 50 additions & 50 deletions src/main/kotlin/kotterknife/ButterKnife.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,117 +12,117 @@ import android.support.v4.app.DialogFragment as SupportDialogFragment
import android.support.v4.app.Fragment as SupportFragment

public fun <V : View> View.bindView(id: Int)
: ReadOnlyProperty<View, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> Activity.bindView(id: Int)
: ReadOnlyProperty<Activity, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> Dialog.bindView(id: Int)
: ReadOnlyProperty<Dialog, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> DialogFragment.bindView(id: Int)
: ReadOnlyProperty<DialogFragment, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> SupportDialogFragment.bindView(id: Int)
: ReadOnlyProperty<SupportDialogFragment, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> Fragment.bindView(id: Int)
: ReadOnlyProperty<Fragment, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> SupportFragment.bindView(id: Int)
: ReadOnlyProperty<SupportFragment, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)
public fun <V : View> ViewHolder.bindView(id: Int)
: ReadOnlyProperty<ViewHolder, V> = required(id, viewFinder)
: ReadOnlyProperty<Any?, V> = required(id, viewFinder)

public fun <V : View> View.bindOptionalView(id: Int)
: ReadOnlyProperty<View, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> Activity.bindOptionalView(id: Int)
: ReadOnlyProperty<Activity, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> Dialog.bindOptionalView(id: Int)
: ReadOnlyProperty<Dialog, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> DialogFragment.bindOptionalView(id: Int)
: ReadOnlyProperty<DialogFragment, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> SupportDialogFragment.bindOptionalView(id: Int)
: ReadOnlyProperty<SupportDialogFragment, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> Fragment.bindOptionalView(id: Int)
: ReadOnlyProperty<Fragment, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> SupportFragment.bindOptionalView(id: Int)
: ReadOnlyProperty<SupportFragment, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)
public fun <V : View> ViewHolder.bindOptionalView(id: Int)
: ReadOnlyProperty<ViewHolder, V?> = optional(id, viewFinder)
: ReadOnlyProperty<Any?, V?> = optional(id, viewFinder)

public fun <V : View> View.bindViews(vararg ids: Int)
: ReadOnlyProperty<View, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> Activity.bindViews(vararg ids: Int)
: ReadOnlyProperty<Activity, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> Dialog.bindViews(vararg ids: Int)
: ReadOnlyProperty<Dialog, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> DialogFragment.bindViews(vararg ids: Int)
: ReadOnlyProperty<DialogFragment, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> SupportDialogFragment.bindViews(vararg ids: Int)
: ReadOnlyProperty<SupportDialogFragment, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> Fragment.bindViews(vararg ids: Int)
: ReadOnlyProperty<Fragment, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> SupportFragment.bindViews(vararg ids: Int)
: ReadOnlyProperty<SupportFragment, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)
public fun <V : View> ViewHolder.bindViews(vararg ids: Int)
: ReadOnlyProperty<ViewHolder, List<V>> = required(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = required(ids, viewFinder)

public fun <V : View> View.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<View, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> Activity.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<Activity, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> Dialog.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<Dialog, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> DialogFragment.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<DialogFragment, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> SupportDialogFragment.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<SupportDialogFragment, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> Fragment.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<Fragment, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> SupportFragment.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<SupportFragment, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)
public fun <V : View> ViewHolder.bindOptionalViews(vararg ids: Int)
: ReadOnlyProperty<ViewHolder, List<V>> = optional(ids, viewFinder)
: ReadOnlyProperty<Any?, List<V>> = optional(ids, viewFinder)

private val View.viewFinder: View.(Int) -> View?
private val View.viewFinder: (Int) -> View?
get() = { findViewById(it) }
private val Activity.viewFinder: Activity.(Int) -> View?
private val Activity.viewFinder: (Int) -> View?
get() = { findViewById(it) }
private val Dialog.viewFinder: Dialog.(Int) -> View?
private val Dialog.viewFinder: (Int) -> View?
get() = { findViewById(it) }
private val DialogFragment.viewFinder: DialogFragment.(Int) -> View?
private val DialogFragment.viewFinder: (Int) -> View?
get() = { dialog?.findViewById(it) ?: view?.findViewById(it) }
private val SupportDialogFragment.viewFinder: SupportDialogFragment.(Int) -> View?
private val SupportDialogFragment.viewFinder: (Int) -> View?
get() = { dialog?.findViewById(it) ?: view?.findViewById(it) }
private val Fragment.viewFinder: Fragment.(Int) -> View?
private val Fragment.viewFinder: (Int) -> View?
get() = { view.findViewById(it) }
private val SupportFragment.viewFinder: SupportFragment.(Int) -> View?
private val SupportFragment.viewFinder: (Int) -> View?
get() = { view!!.findViewById(it) }
private val ViewHolder.viewFinder: ViewHolder.(Int) -> View?
private val ViewHolder.viewFinder: (Int) -> View?
get() = { itemView.findViewById(it) }

private fun viewNotFound(id:Int, desc: KProperty<*>): Nothing =
throw IllegalStateException("View ID $id for '${desc.name}' not found.")

@Suppress("UNCHECKED_CAST")
private fun <T, V : View> required(id: Int, finder: T.(Int) -> View?)
= Lazy { t: T, desc -> t.finder(id) as V? ?: viewNotFound(id, desc) }
private fun <T, V : View> required(id: Int, finder: (Int) -> View?)
= Lazy<T, V> { desc -> finder(id) as V? ?: viewNotFound(id, desc) }

@Suppress("UNCHECKED_CAST")
private fun <T, V : View> optional(id: Int, finder: T.(Int) -> View?)
= Lazy { t: T, desc -> t.finder(id) as V? }
private fun <T, V : View> optional(id: Int, finder: (Int) -> View?)
= Lazy<T, V?> { finder(id) as V? }

@Suppress("UNCHECKED_CAST")
private fun <T, V : View> required(ids: IntArray, finder: T.(Int) -> View?)
= Lazy { t: T, desc -> ids.map { t.finder(it) as V? ?: viewNotFound(it, desc) } }
private fun <T, V : View> required(ids: IntArray, finder: (Int) -> View?)
= Lazy<T, List<V>> { desc -> ids.map { finder(it) as V? ?: viewNotFound(it, desc) } }

@Suppress("UNCHECKED_CAST")
private fun <T, V : View> optional(ids: IntArray, finder: T.(Int) -> View?)
= Lazy { t: T, desc -> ids.map { t.finder(it) as V? }.filterNotNull() }
private fun <T, V : View> optional(ids: IntArray, finder: (Int) -> View?)
= Lazy<T, List<V>> { ids.map { finder(it) as V? }.filterNotNull() }

// Like Kotlin's lazy delegate but the initializer gets the target and metadata passed to it
private class Lazy<T, V>(private val initializer: (T, KProperty<*>) -> V) : ReadOnlyProperty<T, V> {
private class Lazy<T, V>(private val initializer: (KProperty<*>) -> V) : ReadOnlyProperty<T, V> {
private object EMPTY
private var value: Any? = EMPTY

override fun getValue(thisRef: T, property: KProperty<*>): V {
if (value == EMPTY) {
value = initializer(thisRef, property)
value = initializer(property)
}
@Suppress("UNCHECKED_CAST")
return value as V
Expand Down