diff --git a/.gitignore b/.gitignore index 489e3d0..aae09fb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .externalNativeBuild .cxx firebase-debug.log +.worktrees/ diff --git a/vbpd-core/src/test/kotlin/dev/androidbroadcast/vbpd/EagerViewBindingPropertyTest.kt b/vbpd-core/src/test/kotlin/dev/androidbroadcast/vbpd/EagerViewBindingPropertyTest.kt index bfda4a9..6c27941 100644 --- a/vbpd-core/src/test/kotlin/dev/androidbroadcast/vbpd/EagerViewBindingPropertyTest.kt +++ b/vbpd-core/src/test/kotlin/dev/androidbroadcast/vbpd/EagerViewBindingPropertyTest.kt @@ -40,4 +40,15 @@ class EagerViewBindingPropertyTest { val second = property.getValue(thisRef, mockProperty) assertEquals(first, second) } + + @Test + fun `clear does not affect getValue`() { + val binding = createMockBinding() + val property = EagerViewBindingProperty(binding) + val thisRef = Any() + + property.clear() + val result = property.getValue(thisRef, mockProperty) + assertEquals(binding, result) + } } diff --git a/vbpd-reflection/src/main/kotlin/dev/androidbroadcast/vbpd/ViewGroupBindings.kt b/vbpd-reflection/src/main/kotlin/dev/androidbroadcast/vbpd/ViewGroupBindings.kt index 6b2f8a9..fd428cb 100644 --- a/vbpd-reflection/src/main/kotlin/dev/androidbroadcast/vbpd/ViewGroupBindings.kt +++ b/vbpd-reflection/src/main/kotlin/dev/androidbroadcast/vbpd/ViewGroupBindings.kt @@ -14,7 +14,7 @@ import androidx.viewbinding.ViewBinding * * @return [ViewBindingProperty] that holds [ViewBinding] instance */ -@JvmName("viewBindingFragment") +@JvmName("viewBindingViewGroup") public inline fun ViewGroup.viewBinding( createMethod: CreateMethod = CreateMethod.BIND, ): ViewBindingProperty = viewBinding(T::class.java, createMethod) @@ -27,7 +27,7 @@ public inline fun ViewGroup.viewBinding( * * @return [ViewBindingProperty] that holds [ViewBinding] instance */ -@JvmName("viewBindingFragment") +@JvmName("viewBindingViewGroup") @JvmOverloads public fun ViewGroup.viewBinding( viewBindingClass: Class, @@ -50,7 +50,7 @@ public fun ViewGroup.viewBinding( * * @return [ViewBindingProperty] that holds [ViewBinding] instance */ -@JvmName("viewBindingFragment") +@JvmName("viewBindingViewGroupInflate") public inline fun ViewGroup.viewBinding(attachToRoot: Boolean = false): ViewBindingProperty = viewBinding(T::class.java, attachToRoot) @@ -62,7 +62,7 @@ public inline fun ViewGroup.viewBinding(attachToRoot: * * @return [ViewBindingProperty] that holds [ViewBinding] instance */ -@JvmName("viewBindingFragment") +@JvmName("viewBindingViewGroupInflate") public fun ViewGroup.viewBinding( viewBindingClass: Class, attachToRoot: Boolean = false, diff --git a/vbpd/src/main/kotlin/dev/androidbroadcast/vbpd/internal/VbpdUtils.kt b/vbpd/src/main/kotlin/dev/androidbroadcast/vbpd/internal/VbpdUtils.kt index e8c1562..44a25bd 100644 --- a/vbpd/src/main/kotlin/dev/androidbroadcast/vbpd/internal/VbpdUtils.kt +++ b/vbpd/src/main/kotlin/dev/androidbroadcast/vbpd/internal/VbpdUtils.kt @@ -52,7 +52,7 @@ public fun DialogFragment.findRootView( if (viewBindingRootId != 0) requireViewByIdCompat(viewBindingRootId) else this } } else { - return requireView().findViewById(viewBindingRootId) + return requireView().requireViewByIdCompat(viewBindingRootId) } } diff --git a/vbpd/src/test/kotlin/dev/androidbroadcast/vbpd/ActivityViewBindingPropertyTest.kt b/vbpd/src/test/kotlin/dev/androidbroadcast/vbpd/ActivityViewBindingPropertyTest.kt index 8984dfb..dfb96a8 100644 --- a/vbpd/src/test/kotlin/dev/androidbroadcast/vbpd/ActivityViewBindingPropertyTest.kt +++ b/vbpd/src/test/kotlin/dev/androidbroadcast/vbpd/ActivityViewBindingPropertyTest.kt @@ -11,6 +11,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner +import kotlin.reflect.KProperty +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals import kotlin.test.assertNotNull @RunWith(RobolectricTestRunner::class) @@ -55,6 +58,37 @@ class ActivityViewBindingPropertyTest { val activity = controller.get() assertNotNull(activity.binding) + // Verify full lifecycle completes without crash + // onDestroy triggers clear() which nulls binding and unregisters callbacks controller.pause().stop().destroy() } + + @Test + fun `clear resets binding and allows recreation`() { + val mockProperty = mockk>(relaxed = true) + var callCount = 0 + val delegate = + ActivityViewBindingProperty { activity -> + callCount++ + mockk { + every { root } returns View(activity) + } + } + + val controller = + Robolectric + .buildActivity(TestActivity::class.java) + .create() + .start() + .resume() + val activity = controller.get() + + val binding1 = delegate.getValue(activity, mockProperty) + assertEquals(1, callCount) + + delegate.clear() + val binding2 = delegate.getValue(activity, mockProperty) + assertEquals(2, callCount) + assertNotEquals(binding1, binding2, "After clear(), a new binding should be created") + } }