Giter Club home page Giter Club logo

binding's Introduction

Binding

Simple API implement DataBinding and ViewBinding. Welcome star
简单的 API 实现 DataBinding 和 ViewBinding,欢迎 star

English   ·  中文

If the image cannot be viewed, please click here to view it img1 | img2

Thanks

About Binding

Binding has been migrated to Maven Central because jCenter will be deprecated

Binding simplifies the use of DataBinding and ViewBinding, and only requires one line of code to implement DataBinding and ViewBinding.

The future plan of Binding provides a general findViewById solution. Due to the iterative update of technology from butterknife, DataBinding, Kotlin synthesis method (Synthetic view) to the current ViewBinding, there may be new technologies in the future. No matter how the technology changes, just need Update Binding, the external use remains unchanged.

Thank you for your suggestions. At present, Binding has been adapted to a large number of scenarios. At the same time, it also provides a lot of practical cases of DataBinding and ViewBinding. If you encounter Binding incompatible scenarios during use, please raise an issue and I will solve it as soon as possible. .

If this repository is helpful to you, please give me star, thank you very much for your support, and welcome you to submit a PR ❤️❤️❤️

Binding the following advantages:

  • Support using DataBinding or ViewBinding in custom ViewGroup
  • Provides many cases including Ativity, Fragment, Dialog, Adapter, include, merge, ViewStub , Navigation etc.
  • A simple API requires only one line of code to implement DataBinding or ViewBinding
  • Support the use of DataBinding or ViewBinding in the ActivityAppCompatActivityFragmentActivityFragmentDialog
  • Support the use of DataBinding or ViewBinding in the ListAdapterPagedListAdapterPagingDataAdapterRecyclerView.Adapter
  • Support the use of DataBinding and ViewBinding in Navigaion Fragment management framework, BottomSheetDialogFragment and other scenarios
  • Avoid a lot of template code
  • Avoid memory leaks, have life cycle awareness, and automatically destroy data when the life cycle is in onDestroyed()

Download

Binding has been migrated to Maven Central because jCenter will be deprecated

add jcenter

Add the following code to the build.gradle file at the Project level

allprojects {
    repositories {
        // aliyun center 包含 mavenCentral 和  jcenter
        maven { url "https://maven.aliyun.com/repository/public" }
        // maven
        mavenCentral()
    }
}

add dependency

Add the following code to the module level build.gradle file, and you need to enable DataBinding or ViewBinding

android {
    buildFeatures {
        dataBinding = true
        viewBinding = true
    }
}

dependencies {
    implementation 'com.hi-dhl:binding:${binding_version}'
}

The latest version

simple API

Binding provides a simple API as shown below.

ViewBinding

val binding: ActivityViewBindBinding by viewbind()

DataBinding

val binding: ActivityDataBindBinding by databind(R.layout.activity_data_bind)
or
val binding: ActivityDataBindBinding by databind()

let's see how to use in Ativity, Fragment, Dialog, Adapter, include, merge, ViewStub , Navigation , ViewGroup etc.

Usage

Use DataBinding and ViewBinding in Custom ViewGroup,

  • Use of ViewBinding :

    • When the root layout is a non-merge label, use this method to initialize val binding: LayoutViewCustomBinding by viewbind()
    • When the root layout is the merge tag, use this method for initialization val binding: LayoutViewCustomBinding by viewbind(this)
  • Use of DataBinding

    val binding: LayoutViewCustomDataBinding by databind(R.layout.layout_view_custom_data)
    

A detailed example is shown below。

class ViewBindCustomView @JvmOverloads constructor(
    context: Context,
    attr: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : LinearLayout(context, attr, defStyleAttr) {

    // ViewBinding
    
    // When the root layout is the merge tag, use this method for initialization
    val binding: LayoutViewCustomBinding by viewbind(this)
    
    // When the root layout is a non-merge label, use this method to initialize
    val binding: LayoutViewCustomBinding by viewbind()
    
    // DataBinding
    val binding: LayoutViewCustomDataBinding by databind(R.layout.layout_view_custom_data)

    init {
        with(binding) {
            result.setText("Use DataBinding and ViewBinding in Custom ViewGroup")
        }
    }
}

Use DataBinding and ViewBinding in Adapter (ListAdapter, PagingDataAdapter, RecyclerView.Adapter, etc.), add by viewbind() or by databind(), the example is as follows,see example

class ProductViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    
    // DataBinding
    val binding: RecycleItemProductBinding by databind()

    fun bindData(data: Product?, position: Int) {
        binding.apply {
            product = data
            executePendingBindings()
        }
    }
}

class ProductViewHolderHeader(view: View) : RecyclerView.ViewHolder(view) {

    // ViewBinding
    val binding: RecycleItemProductHeaderBinding by viewbind()

    fun bindData(data: Product?, position: Int) {
        binding.apply {
            name.text = "通过 ViewBinding 绑定的 head"
        }
    }
}

use in Activity, AppCompatActivity, and FragmentActivity, add by viewbind() or by databind(R.layout.activity_main).

class MainActivity : AppCompatActivity() {

    // DataBinding
    val binding: ActivityMainBinding by databind(R.layout.activity_main)
    
    // ViewBinding
    val binding: ActivityMainBinding by viewbind()
}

There are two ways in Fragment, and their use positions are different, as shown below.

Method 1:
class FragmentNav1 : Fragment() {
    
    // DataBinding
  	val binding: FragmentMainBinding by databind()
    
    // ViewBinding
  	 val binding: FragmentMainBinding by viewbind()
  
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return binding.root
    }
}

Method 2:
class FragmentNav1 : Fragment(R.layout.fragment_main) {
    
    // DataBinding
  	val binding: FragmentMainBinding by databind()
    
    // ViewBinding
  	 val binding: FragmentMainBinding by viewbind()
  
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.apply { textView.setText("Binding") }
    }
}

The usage in Dialog is as follows。

class AppDialog(context: Context) : Dialog(context, R.style.AppDialog) {

    // DataBinding
    val binding: DialogAppBinding by databind(R.layout.dialog_data_binding)
    
    // ViewBinding
    val binding: DialogAppBinding by viewbind()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.apply { result.setText("DialogAppBinding") }
    }
}

or add life cycle listening

class AppDialog(context: Context,lifecycle: Lifecycle) : Dialog(context, R.style.AppDialog) {

    // use DataBinding life cycle listening
    val binding: DialogAppBinding by databind(R.layout.dialog_data_binding, lifecycle)
    
    // use ViewBinding life cycle listening
    val binding: DialogAppBinding by viewbind(lifecycle)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.apply { result.setText("DialogAppBinding") }
    }
}

Extension method that supports DataBinding to bind data when initialized,Thanks to @br3ant contribute,see example

val binding: ActivityDataBindBinding by databind(R.layout.activity_data_bind) {
    val account = Account()
    account.name = "test"
    this.account = account
}

Do not want to generate a binding class for a layout, add the following attributes to the root view of the layout file

<LinearLayout tools:viewBindingIgnore="true" >
</LinearLayout>

proguard

-keepclassmembers class ** implements androidx.viewbinding.ViewBinding {
    public static ** bind(***);
    public static ** inflate(***);
    public static ** inflate(**,**);
}

change log

2023-04-13(V1.2.0)

  • 兼容 lifecycle 2.6.0 FullLifecycleObserver 被删除的问题

2022-10-07(V1.1.9)

  • Compatible with jdk >= 1.8 version

2022-7-13(V1.1.7)

  • 兼容不传 ViewGroup 的情况#34

2022-5-12(V1.1.5)

  • 修改 ViewGroup 销毁的时候释放资源 #33

2022-5-03(V1.1.4)

  • 修复了生命周期问题
  • 修复了销毁之后再次使用,由于 delegate property 会被再次初始化,出现的异常 #31

2021-5-09(V1.1.3)

  • fix not found inflate(LayoutInflater) in the ViewGroup #26

2021-3-09(V1.1.2)

  • Fixed the issue that the diff with Fragment Lifecycle #18
  • Binding has been migrated to Maven Central

2021-1-25(V1.0.9)

  • Fixed the issue that the diff with Fragment Lifecycle and View Lifecycle #15
  • Fixed the issue that the layout attribute of the root view of Fragment is invalid #13

2021-1-14(V1.0.8)

  • Support using DataBinding or ViewBinding in custom ViewGroup
  • add use cases in ViewGroup

2020-12-31

2020-12-28(V1.0.6)

  • Support Activity and Fragment to automatically bind LifecycleOwner。see issue

2020-12-21(V1.0.5)

  • Support using DataBinding and ViewBinding in navigation fragment,see example

2020-12-17(V1.0.4)

  • Support all Adapters related to RecyclerView.ViewHolder (ListAdapter, PagingDataAdapter, RecyclerView.Adapter, etc.) to use DataBinding and ViewBinding,see example

  • Extension method that supports DataBinding to bind data when initialized,Thanks to @br3ant contribute,see example

2020-12-15(V1.0.3)

  • Use of DataBinding in Dialog, by databind(R.layout.dialog_data_binding) or by databind(R.layout.dialog_data_binding, lifecycle)
  • Avoid memory leaks, have life cycle awareness, and automatically destroy data when the life cycle is in onDestroyed()
  • The minimum SDK version is reduced to 14

2020-12-14:

  • Demo adds DataBinding example
  • Demo adds ViewBinding example
  • Demo adds kotlin-parcelize example

2020-12-13(V1.0.1)

  • Use ViewBinding in Dialog, add by viewbind() or by viewbind(lifecycle)

2020-12-12(V1.0.0)

  • A simple API requires only one line of code to implement DataBinding or ViewBinding
  • Support the use of DataBinding or ViewBinding in the ActivityAppCompatActivityFragmentActivityFragment
  • Avoid a lot of template code
  • Avoid memory leaks, have life cycle awareness, and automatically destroy data when the life cycle is in onDestroyed()

contact me

  • 个人微信:hi-dhl
  • 公众号:ByteCode,包含 Jetpack ,Kotlin ,Android 10 系列源码,译文,LeetCode / 剑指 Offer / 多线程 / 国内外大厂算法题 等等一系列文章


最后推荐我一直在更新维护的项目和网站:

  • 计划建立一个最全、最新的 AndroidX Jetpack 相关组件的实战项目 以及 相关组件原理分析文章,正在逐渐增加 Jetpack 新成员,仓库持续更新,欢迎前去查看:AndroidX-Jetpack-Practice

  • LeetCode / 剑指 offer / 国内外大厂面试题 / 多线程 题解,语言 Java 和 kotlin,包含多种解法、解题思路、时间复杂度、空间复杂度分析

  • 最新 Android 10 源码分析系列文章,了解系统源码,不仅有助于分析问题,在面试过程中,对我们也是非常有帮助的,仓库持续更新,欢迎前去查看 Android10-Source-Analysis

  • 整理和翻译一系列精选国外的技术文章,每篇文章都会有译者思考部分,对原文的更加深入的解读,仓库持续更新,欢迎前去查看 Technical-Article-Translation

  • 「为互联网人而设计,国内国外名站导航」涵括新闻、体育、生活、娱乐、设计、产品、运营、前端开发、Android 开发等等网址,欢迎前去查看 为互联网人而设计导航网站

binding's People

Contributors

br3ant avatar hi-dhl avatar singledog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

binding's Issues

在BRAVH中怎么使用呢

比如在BRAVH中使用viewbind, 不会自己去写viewholder, 是直接使用adapter 提供的 BaseViewHolder, 照着文档中的例子写,编译通不过

SmartRefreshLayout自定义RefreshHeader时,报java.lang.NoSuchMethodException的错误

升级到1.1.5版本之后,SmartRefreshLayout自定义RefreshHeader时,报java.lang.NoSuchMethodException的错误:
Caused by: java.lang.NoSuchMethodException:com.xxx.xxx.databinding.LayoutCommonRefreshHeaderBinding.inflate [class android.view.LayoutInflater, class android.view.ViewGroup]
at java.lang.Class.getMethod(Class.java:2072)
at java.lang.Class.getMethod(Class.java:1693)
at com.hi.dhl.binding.ReflectExtKt.inflateMethodWithViewGroup(ReflectExt.kt:21)
at com.hi.dhl.binding.viewbind.ViewGroupViewBinding.(ViewGroupViewBinding.kt:36)
查看源码源码发现1.1.5版本viewbind扩展方法强制要求传入viewGroup引起的,自定义的RefreshHeader是通过addview方式添加进SmartRefreshLayout里面的。viewbind改回不传入viewGroup方式可正常使用,建议增加viewGroup可空的方法。

遇到个bug

场景: 一个activity,监听viewmodel中的livedata,两个fragment,两个fragment中都有一个按钮,点击就会通过viewmodel切换显示。 发现各自点击两次后就不能响应点击事件了

使用viewbind时,如何在使用xml布局的自定义ViewGroup中使用呢

自定义ViewGroup布局名称layout_empty_tip,根标签使用了<merge>
声明了private val binding: LayoutEmptyTipBinding by viewbind()
但是运行报错了

java.lang.NoSuchMethodException: inflate [class android.view.LayoutInflater]
at java.lang.Class.getMethod(Class.java:2068)
at java.lang.Class.getMethod(Class.java:1690)
at com.hi.dhl.binding.ReflectExtKt.inflateMethod(ReflectExt.kt:17)
at com.hi.dhl.binding.viewbind.ViewGroupViewBinding.(ViewGroupViewBinding.kt:24)

看了下应该是反射没找到inflate方法

fun Class.inflateMethod() = getMethod(INFLATE_NAME, LayoutInflater::class.java)

但是不知道怎么解决

NoSuchMethodException问题

问题: 在继承系统布局中,如果布局文件的根是merge标签,会抛出NoSuchMethodException;替换为ConstraintLayout等则不会。调试过,貌似原因是getMethod里调用的getPublicMethodRecursive只匹配了仅有LayoutInflater类型参数的infalte方法

merge标签产生的binding类也只有一个inflate(@nonnull LayoutInflater inflater, @nonnull ViewGroup parent)这种签名的,作者有时间看看是不是这样?
备注:混淆添加了的

反射调用时报NoSuchMethodException崩溃

Oppo R17
binding:1.0.7

Caused by: java.lang.NoSuchMethodException: com.datedu.lib_camera.databinding.ActivityTakeVideoBinding.inflate [class android.view.LayoutInflater]
at java.lang.Class.getMethod(Class.java:2072)
at java.lang.Class.getMethod(Class.java:1693)
at com.hi.dhl.binding.e.b(ReflectExt.kt:1)
at com.hi.dhl.binding.g.a.(ActivityViewBinding.kt:2)
at com.datedu.camera.ui.TakeVideoActivity.(TakeVideoActivity.kt:2)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:1)
at android.app.Instrumentation.newActivity(Instrumentation.java:1251)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3399)

反馈个bug,我用viewpager2,从kotlin-android-extensions改成这个框架报错

先是报错 FragmentManager is already executing transactions
然后我改了FragmentStateAdapter的条件
报错变成了Fragment no longer exists
但是FragmentStateAdapter saveState是final方法 和viewpager2 也是final class
所以我还原代码kotlin-android-extensions的写法就没有报错了
我应用的UI是下面三个tab,一个tab用viewpager2包两个 Fragment
在tab上切来切去就报错

bug onGetLayoutInflater

1 androidx.fragment.app.Fragment.getLayoutInflater(Fragment.java:1503)

2 androidx.fragment.app.Fragment.onGetLayoutInflater(Fragment.java:1452)
3 androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1484)
4 androidx.fragment.app.Fragment.getLayoutInflater(Fragment.java:1469)
5 com.hi.dhl.binding.viewbind.FragmentViewBinding.getValue(FragmentViewBinding.kt:34)
6 com.snmi.smclass.ui.main.SmClass5Fragment.getBinding(Unknown Source:10)
7 com.snmi.smclass.ui.main.SmClass5Fragment.access$getBinding$p(SmClass5Fragment.kt:73)
8 com.snmi.smclass.ui.main.SmClass5Fragment$loadSemesterBeans$1$2.invokeSuspend(SmClass5Fragment.kt:496)
9 kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
10 kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
11 android.os.Handler.handleCallback(Handler.java:790)
12 android.os.Handler.dispatchMessage(Handler.java:99)
13 android.os.Looper.loop(Looper.java:210)
14 android.app.ActivityThread.main(ActivityThread.java:7080)
15 java.lang.reflect.Method.invoke(Native Method)
16 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
17 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:863)

在Navigation启动的Fragment中使用报错

使用Navigation启动Fragment报错如下:

Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.hi.dhl.binding.viewbind.FragmentViewBinding.getValue(FragmentViewBinding.kt:34)
        ......
Caused by: java.lang.ClassCastException: androidx.appcompat.widget.AppCompatImageView cannot be cast to android.widget.TextView
        at fun.inaction.stallx.databinding.FragmentSearchBinding.bind(FragmentSearchBinding.java:78)
        at fun.inaction.stallx.databinding.FragmentSearchBinding.inflate(FragmentSearchBinding.java:68)
        at fun.inaction.stallx.databinding.FragmentSearchBinding.inflate(FragmentSearchBinding.java:58)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.hi.dhl.binding.viewbind.FragmentViewBinding.getValue(FragmentViewBinding.kt:34)

报错的代码:

class FragmentViewBinding<T : ViewBinding>(
    classes: Class<T>,
    fragment: Fragment
) : FragmentDelegate<T>(fragment) {
... 省略

bind = layoutInflater.invoke(null, thisRef.layoutInflater) as T

... 省略

ActivityViewBinding 是否应该主动在onCreate时调用setContentView

ActivityViewBinding 里是在委托首次赋值时调用的setContentView,根据使用习惯的不同,会使得调用时机不明确:例如可能在数据请求返回之后才遇到首次操作UI的时机,那么在此之前委托的属性都没被获取、不会调用setContentView,使得页面一直显示空白。

对于类似的情况,是不是应该监听Activity的生命周期,主动在 ON_CREATE 事件里调用setContentView

请问如何迁移呢

请问项目从butterknife或者fvb,如何迁移过来呢?好像viewbinding一打开,所以xml就被解析了。

onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager

Exception java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.
at androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1673)
at androidx.fragment.app.Fragment.onGetLayoutInflater (Fragment.java:1622)
at androidx.fragment.app.Fragment.performGetLayoutInflater (Fragment.java:1654)
at androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1639)
at com.hi.dhl.binding.viewbind.FragmentViewBinding.getValue (FragmentViewBinding.kt:51)
at com.aly.ticktube.ui.fragment.VideoFragment. (VideoFragment.kt:39)
at com.aly.ticktube.ui.fragment.VideoFragment.access$getMFragment (VideoFragment.kt:37)
at com.aly.ticktube.ui.fragment.VideoFragment$initView$6$1.onAnimationEnd (VideoFragment.kt:123)
at android.animation.AnimatorSet.onChildAnimatorEnded (AnimatorSet.java:829)
at android.animation.AnimatorSet.-wrap1 (AnimatorSet.java)
at android.animation.AnimatorSet$AnimatorSetListener.onAnimationEnd (AnimatorSet.java:784)
at android.animation.ValueAnimator.endAnimation (ValueAnimator.java:1153)
at android.animation.ValueAnimator.doAnimationFrame (ValueAnimator.java:1313)
at android.animation.AnimationHandler.doAnimationFrame (AnimationHandler.java:146)
at android.animation.AnimationHandler.-wrap2 (AnimationHandler.java)
at android.animation.AnimationHandler$1.doFrame (AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run (Choreographer.java:928)
at android.view.Choreographer.doCallbacks (Choreographer.java:705)
at android.view.Choreographer.doFrame (Choreographer.java:637)
at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:916)
at android.os.Handler.handleCallback (Handler.java:751)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6816)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1565)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1453)

Fragment生命周期监听方法不正确

当前的监听方法通过fragment.lifecycle添加了Observer,
fragment.lifecycle关联的是fragment的生命周期,而非fragment.view的生命周期,

fragment.lifecycle.addObserver { destroyed() }

由于fragment.view活跃的生命周期存在明显比fragment活跃生命周期短的情况,
(如采用Navigation库管理fragment(attach/detach))
正确的做法是采用fragment.viewLifecycleOwner.lifecycle添加Observer。

Simple one-liner ViewBinding in Fragments and Activities with Kotlin
中fragment生命周期监听的方法是正确的
(其中onDestroy回调与fragment.onDestroyView()回调对应)

fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onCreate(owner: LifecycleOwner) {
        fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
            viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
                override fun onDestroy(owner: LifecycleOwner) {
                    binding = null
                }
            })
        }
    }
})

PS: observers可以不额外手动remove,因为fragment.lifecycle和LiveData都在DESTROYED时做了反注册。

自定义View的混淆规则

作者你好,之前向你反馈的自定义View使用viewbind导致的崩溃问题,升级1.1.3版本后,已经可以正常使用。但是混淆规则却没有跟着更新,这会导致自定义View的ViewBinding类中的inflate方法被混淆掉,导致异常。所以混淆规则需要新增一个public static ** inflate(**,**);,作者可以试一试

Fatal Exception: java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.

Fatal Exception: java.lang.IllegalStateException
onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.

androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1673)
androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1639)
com.hi.dhl.binding.databind.FragmentDataBinding.getValue (FragmentDataBinding.java:35)

报错 FragmentDataBinding 行数: 35,但使用的Fragment(layoutId: Int) 构造方法,

按常理:在onViewCreated() 方法后调用,

FragmentDataBinding 中第 35 行
thisRef.view == null 应该为 false,除非什么异常情况导致执行此句,

然后,想到可能和fragment 的恢复有关系,恢复的时候 走的是 Fragment() 无参数方法,layoutId = 0, 所以 view 为空

目前尝试在 onSaveInstance() 里面保存 layoutId,在恢复时重新将 layoutId 还原

所以也不全是这个库的问题,只是报错的地方在库里面而已

同一类型的多个 fragment 实例的 binding.view 引用错位问题

代码结构:
Activity -> 上下两个 Fragment (同一个类型的,2个实例)

具体使用:

class ImageAdFragment : AdFragment(R.layout.fragment_image_ad) {

    private val binding by viewbind<FragmentImageAdBinding>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Utils.log("加载图片${model.url}")
        Glide.with(binding.ivImg.context).asBitmap().load(File(model.url)).into(binding.ivImg)
    }
}

导致第二个 fragment 的图片,展示到了第一个 fragment 里的 ImageView 上,
然后,第二个 Fragment 显示空白...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.