From f20a6d932ca70ac8d853ab1e002320db7ee1236e Mon Sep 17 00:00:00 2001 From: hi-dhl Date: Thu, 12 May 2022 14:12:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20ViewGroup=20=E5=9C=A8=20databinding=20?= =?UTF-8?q?=E9=94=80=E6=AF=81=E7=9A=84=E6=97=B6=E5=80=99=E9=87=8A=E6=94=BE?= =?UTF-8?q?=E8=B5=84=E6=BA=90=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E6=A3=80=E6=9F=A5=20(#33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binding/viewbind/ViewBindCustomView.kt | 2 +- binding/build.gradle | 2 +- .../binding/databind/FragmentDataBinding.kt | 16 +++++++++++ .../binding/databind/ViewGroupDataBinding.kt | 23 ++++++++++++++++ .../com/hi/dhl/binding/ext/ComponentExt.kt | 27 ++++++++++--------- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/hi/dhl/demo/binding/viewbind/ViewBindCustomView.kt b/app/src/main/java/com/hi/dhl/demo/binding/viewbind/ViewBindCustomView.kt index dc100e4..df69044 100644 --- a/app/src/main/java/com/hi/dhl/demo/binding/viewbind/ViewBindCustomView.kt +++ b/app/src/main/java/com/hi/dhl/demo/binding/viewbind/ViewBindCustomView.kt @@ -24,7 +24,7 @@ class ViewBindCustomView @JvmOverloads constructor( lateinit var onDialogClickListener: OnDialogClickListener // 当根布局为 merge 标签,使用此方法进行初始化 - val binding: LayoutViewCustomBinding by viewbind(this) + val binding: LayoutViewCustomBinding by viewbind() // 当根布局是非 merge 标签,使用此方法进行初始化 // val binding: LayoutViewCustomBinding by viewbind() diff --git a/binding/build.gradle b/binding/build.gradle index 5dfa509..8eee856 100644 --- a/binding/build.gradle +++ b/binding/build.gradle @@ -47,4 +47,4 @@ dependencies { implementation "androidx.recyclerview:recyclerview:$recyclerview" } -apply from: 'gradle-mvn-push.gradle' \ No newline at end of file +//apply from: 'gradle-mvn-push.gradle' \ No newline at end of file diff --git a/binding/src/main/java/com/hi/dhl/binding/databind/FragmentDataBinding.kt b/binding/src/main/java/com/hi/dhl/binding/databind/FragmentDataBinding.kt index 8b74b57..6af4762 100644 --- a/binding/src/main/java/com/hi/dhl/binding/databind/FragmentDataBinding.kt +++ b/binding/src/main/java/com/hi/dhl/binding/databind/FragmentDataBinding.kt @@ -3,8 +3,10 @@ package com.hi.dhl.binding.databind import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle import com.hi.dhl.binding.base.FragmentDelegate import com.hi.dhl.binding.inflateMethod +import java.lang.Exception import kotlin.reflect.KProperty /** @@ -29,6 +31,20 @@ class FragmentDataBinding( } ?: let { + try { + /** + * 检查目的,是为了防止在 onCreateView() or after onDestroyView() 使用 binding。 + * 另外在销毁之后,如果再次使用,由于 delegate property 会被再次初始化出现的异常 + * + * 捕获这个异常的原因,是为了兼容之前的版本,防止因为升级,造成崩溃 + */ + check(thisRef.viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) { + "cannot use binding in before onCreateView() or after onDestroyView() from 1.1.4. about [issue](https://github.com/hi-dhl/Binding/issues/31#issuecomment-1109733307)" + } + } catch (e: Exception) { + e.printStackTrace() + } + val bind: T if (thisRef.view == null) { // 这里为了兼容在 navigation 中使用 Fragment diff --git a/binding/src/main/java/com/hi/dhl/binding/databind/ViewGroupDataBinding.kt b/binding/src/main/java/com/hi/dhl/binding/databind/ViewGroupDataBinding.kt index 16d2225..87a1c6d 100644 --- a/binding/src/main/java/com/hi/dhl/binding/databind/ViewGroupDataBinding.kt +++ b/binding/src/main/java/com/hi/dhl/binding/databind/ViewGroupDataBinding.kt @@ -1,10 +1,15 @@ package com.hi.dhl.binding.databind +import android.app.Activity +import android.os.Build import android.view.LayoutInflater import android.view.ViewGroup +import androidx.activity.ComponentActivity import androidx.annotation.LayoutRes import androidx.databinding.DataBindingUtil import androidx.viewbinding.ViewBinding +import com.hi.dhl.binding.observerWhenDestroyed +import com.hi.dhl.binding.registerLifecycleBelowQ import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -20,11 +25,29 @@ class ViewGroupDataBinding( classes: Class, @LayoutRes val resId: Int, val inflater: LayoutInflater, + val viewGroup: ViewGroup? = null, private var block: (T.() -> Unit)? = null ) : ReadOnlyProperty { private var viewBinding: T? = null + init { + viewGroup?.apply { + when (context) { + is ComponentActivity -> { + (context as ComponentActivity).lifecycle.observerWhenDestroyed { destroyed() } + } + is Activity -> { + val activity = context as Activity + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + activity.observerWhenDestroyed { destroyed() } + } else { + activity.registerLifecycleBelowQ { destroyed() } + } + } + } + } + } override fun getValue(thisRef: ViewGroup, property: KProperty<*>): T { return viewBinding?.run { this diff --git a/binding/src/main/java/com/hi/dhl/binding/ext/ComponentExt.kt b/binding/src/main/java/com/hi/dhl/binding/ext/ComponentExt.kt index 69c16d7..1ffc647 100644 --- a/binding/src/main/java/com/hi/dhl/binding/ext/ComponentExt.kt +++ b/binding/src/main/java/com/hi/dhl/binding/ext/ComponentExt.kt @@ -72,19 +72,21 @@ inline fun RecyclerView.ViewHolder.databind(noinli inline fun ViewGroup.databind(@LayoutRes resId: Int) = ViewGroupDataBinding( - T::class.java, - resId, - LayoutInflater.from(getContext()) + classes = T::class.java, + resId = resId, + inflater = LayoutInflater.from(getContext()), + viewGroup = this ) inline fun ViewGroup.databind( @LayoutRes resId: Int, noinline block: (T.() -> Unit) ) = ViewGroupDataBinding( - T::class.java, - resId, - LayoutInflater.from(getContext()), - block + classes = T::class.java, + resId = resId, + inflater = LayoutInflater.from(getContext()), + viewGroup = this, + block = block ) inline fun Activity.viewbind() = @@ -109,13 +111,14 @@ inline fun RecyclerView.ViewHolder.viewbind() = ViewHolderViewBinding(T::class.java) inline fun ViewGroup.viewbind() = ViewGroupViewBinding( - T::class.java, - LayoutInflater.from(getContext()) + classes = T::class.java, + inflater = LayoutInflater.from(getContext()), + viewGroup = this ) inline fun ViewGroup.viewbind(viewGroup: ViewGroup) = ViewGroupViewBinding( - T::class.java, - LayoutInflater.from(getContext()), - viewGroup + classes = T::class.java, + inflater = LayoutInflater.from(getContext()), + viewGroup = viewGroup ) \ No newline at end of file