Coder Social home page Coder Social logo

androidbroadcast / viewbindingpropertydelegate Goto Github PK

View Code? Open in Web Editor NEW
1.4K 18.0 101.0 547 KB

Make work with Android View Binding simpler

Home Page: https://proandroiddev.com/make-android-view-binding-great-with-kotlin-b71dd9c87719

License: Apache License 2.0

Kotlin 100.00%

viewbindingpropertydelegate's Introduction

Maven Central

ViewBindingPropertyDelegate

Make work with Android View Binding simpler. The library:

  • manages ViewBinding lifecycle and clears the reference to it to prevent memory leaks
  • eliminates the need to keep nullable references to Views or ViewBindings
  • creates ViewBinding lazily

The library comes in two flavors: with and without reflection. The artifacts are respectively: viewbindingpropertydelegate and viewbindingpropertydelegate-noreflection. Prefer to use the one without reflection for better performance

IMPORTANT: Enable ViewBinding before using the library

Each Gradle module in your project where you need to use ViewBinding must be properly configured. Refer to the official guide on how to do that

Add the library to a project

allprojects {
  repositories {
    mavenCentral()
  }
}

dependencies {
    // reflection-based flavor
    implementation 'com.github.kirich1409:viewbindingpropertydelegate-full:1.5.9'
    
    // reflection-free flavor
    implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.9'
}

Samples

class ProfileFragment : Fragment(R.layout.profile) {

    // reflection API and ViewBinding.bind are used under the hood
    private val viewBinding: ProfileBinding by viewBinding()

    // reflection API and ViewBinding.inflate are used under the hood
    private val viewBinding: ProfileBinding by viewBinding(createMethod = CreateMethod.INFLATE)

    // no reflection API is used under the hood
    private val viewBinding by viewBinding(ProfileBinding::bind)
}
class ProfileActivity : AppCompatActivity(R.layout.profile) {

    // reflection API is used under the hood
    private val viewBinding: ProfileBinding by viewBinding(R.id.container)

    // no reflection API is used under the hood
    private val viewBinding by viewBinding(ProfileBinding::bind, R.id.container)
}

License

Copyright 2020-2023 Kirill Rozov

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

viewbindingpropertydelegate's People

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

viewbindingpropertydelegate's Issues

Recycler ViewHolder usability

Is this usable in a RecyclerView ViewHolder?

If so, the README should be expanded since it only contains usability in activities, fragments and dialogs.
If not that would be a nice feature.

ViewBinding can't be shared

Hello,

I still got the issue #16 even with using 1.2.1 , I found that when I remove binding.rvSearchHistory.adapter = null from onDestroyView then it is working fine, but I can't really remove this line because it clears the reference to the adapter and prevent leaks in my application.

Nullable views

Can we access views in safe style via Elvis operator? It could be helpful in some cases during migration from Kotlin synthetics

Can not find Create Method

java.lang.NoClassDefFoundError: Failed resolution of: Lby/kirich1409/viewbindingdelegate/CreateMethod;

Supports for `merge` tag?

I didn't find documentation regarding this functionality please guide me if it's exist already, otherwise any milestone to support it?

How to use viewbinding delegate for activity correctly? App crashes with: Unable to start activity ComponentInfo

I am trying to use the viewbinding delegate in my mainactivity. The problem is that my app instantly crashes, what am I doing wrong?

MainActivity

@androidentrypoint

class MainActivity : AppCompatActivity() {
    private val mainBinding: ActivityMainBinding by viewBinding()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        changeBottomNavWhenUserLoggedIn(true)
    }

    private fun changeBottomNavWhenUserLoggedIn(loggedIn: Boolean) {
        if (loggedIn){
            setUpBottomNav(R.menu.bottom_nav_menu_logged_in)
        } else {
            setUpBottomNav(R.menu.bottom_nav_menu_logged_out)
        }
    }

    private fun setUpBottomNav(newMenu: Int) = with(mainBinding.bottomNavigationView) {
        menu.clear()
        inflateMenu(newMenu)
        setupWithNavController(findNavController(R.id.fragment_container))
    }

    fun hideBottomNav() {
        mainBinding.bottomNavigationView.visibility = View.GONE
    }

    fun showBottomNav() {
        mainBinding.bottomNavigationView.visibility = View.VISIBLE
    }

    fun isBottomNavVisible(): Boolean {
        return mainBinding.bottomNavigationView.visibility == View.VISIBLE
    }
}

Layout

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".framework.ui.view.MainActivity">

        <fragment
            android:id="@+id/fragment_container"
            android:name="com.example.app.framework.ui.view.utils.MainNavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="@dimen/wrapContent"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/nav_main" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:itemHorizontalTranslationEnabled="false"
            app:labelVisibilityMode="labeled"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:menu="@menu/bottom_nav_menu_logged_out" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Crash log

2020-12-11 23:14:57.457 11101-11101/com.example3000.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example3000.app, PID: 11101
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example3000.app/com.example3000.app.framework.ui.view.MainActivity}: java.lang.reflect.InvocationTargetException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at by.kirich1409.viewbindingdelegate.ActivityInflateViewBinder.bind(ActivityInflateBindings.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity$$special$$inlined$inflateViewBindingActivity$1.invoke(ActivityInflateBindings.kt:44)
        at com.example3000.app.framework.ui.view.MainActivity$$special$$inlined$inflateViewBindingActivity$1.invoke(Unknown Source:2)
        at by.kirich1409.viewbindingdelegate.ViewBindingProperty.getValue(ViewBindingProperty.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity.getMainBinding(Unknown Source:7)
        at com.example3000.app.framework.ui.view.MainActivity.setUpBottomNav(MainActivity.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity.changeBottomNavWhenUserLoggedIn(MainActivity.kt:25)
        at com.example3000.app.framework.ui.view.MainActivity.onCreate(MainActivity.kt:20)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
     Caused by: android.view.InflateException: Binary XML file line #11 in com.example3000.app:layout/activity_main: Binary XML file line #11 in com.example3000.app:layout/activity_main: Error inflating class fragment
     Caused by: android.view.InflateException: Binary XML file line #11 in com.example3000.app:layout/activity_main: Error inflating class fragment
     Caused by: java.lang.IllegalArgumentException: Binary XML file line #11: Duplicate id 0x7f09013f, tag null, or parent id 0xffffffff with another fragment for com.example3000.app.framework.ui.view.utils.MainNavHostFragment
        at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:116)
        at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
        at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
        at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
        at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1069)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:997)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:126)
        at androidx.databinding.ViewDataBinding.inflateInternal(ViewDataBinding.java:1368)
        at com.example3000.app.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:62)
2020-12-11 23:14:57.458 11101-11101/com.example3000.app E/AndroidRuntime:     at com.example3000.app.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:48)
        at java.lang.reflect.Method.invoke(Native Method)
        at by.kirich1409.viewbindingdelegate.ActivityInflateViewBinder.bind(ActivityInflateBindings.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity$$special$$inlined$inflateViewBindingActivity$1.invoke(ActivityInflateBindings.kt:44)
        at com.example3000.app.framework.ui.view.MainActivity$$special$$inlined$inflateViewBindingActivity$1.invoke(Unknown Source:2)
        at by.kirich1409.viewbindingdelegate.ViewBindingProperty.getValue(ViewBindingProperty.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity.getMainBinding(Unknown Source:7)
        at com.example3000.app.framework.ui.view.MainActivity.setUpBottomNav(MainActivity.kt:31)
        at com.example3000.app.framework.ui.view.MainActivity.changeBottomNavWhenUserLoggedIn(MainActivity.kt:25)
        at com.example3000.app.framework.ui.view.MainActivity.onCreate(MainActivity.kt:20)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Thank you

Pass LayoutInflater

I would like to pass a LayoutInflater.
Normally I did it like this:

private lateinit var binding: FragmentExampleBinding

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    // doing some changes to inflater here
    binding = FragmentExampleBinding.inflate(inflater, container, false)
    return binding.root
}

Is it possible to extend the current delegation by passing these parameter?

LayoutViewBinding, for custom views

Thanks for this wonderful library @kirich1409 ! I'm really enjoying working with the non-reflection delegates

However, I was tinkering around for some ways to make the bindings in custom views delegated

Before:

// layout XML: R.layout.layout_custom
class CustomLayout @JvmOverloads constructor(...) : FrameLayout(...) {
  private val binding = LayoutCustomBinding.inflate(LayoutInflater.from(context), this)
}

My Delegate property:

abstract class LayoutBindingProperty<in R : View, T : ViewBinding>(private val binder: (R) -> T) : ReadOnlyProperty<R, T> {

  private var viewBinding: T? = null

  protected abstract fun getLifecycleOwner(thisRef: R): LifecycleOwner?    // Don't know what to do with this, maybe some optimizations? Or maybe use OnAttachStateChangeListener?

  @MainThread override fun getValue(thisRef: R, property: KProperty<*>): T {
    viewBinding?.let { return it }
    val binding = binder(thisRef)
    viewBinding = binding
    return binding
  }
}

private class LayoutViewBindingProperty<V : View, T : ViewBinding>(
  viewBinder: (V) -> T
) : LayoutBindingProperty<V, T>(viewBinder) {
  override fun getLifecycleOwner(thisRef: V): LifecycleOwner? = thisRef.findViewTreeLifecycleOwner()    // Or ViewTreeLifecycleOwner.get(thisRef), from `lifecycle-*-ktx:2.3.0-rc01`
}

fun <V : View, T : ViewBinding> layoutViewBinding(binder: (V) -> T): LayoutBindingProperty<V, T> = LayoutViewBindingProperty(binder)

inline fun <V : ViewGroup, T : ViewBinding> V.viewBinding(crossinline vbFactory: (LayoutInflater, ViewGroup) -> T): LayoutBindingProperty<V, T> =
  layoutViewBinding { vbFactory(LayoutInflater.from(context), this) }

After using delegate property:

// layout XML: R.layout.layout_custom
class CustomLayout @JvmOverloads constructor(...) : FrameLayout(...) {
  private val binding by viewBinding(LayoutCustomBinding::inflate)
}

I mean this approach is working, but I'm thinking is there any way of optimizing this approach?

To reflection or not to reflection

Hello, It's more of a question than a real issue,

I'm trying out your amazing library and while I was looking at the README, I've seen it was possible not to use reflection, but I don't really understand the pros/cons of using it or not.

I'm working with databinding actually and I wanted to this syntax
private val binding by viewBinding(FragmentProfileBinding::bind) but the following error:

Property delegate must have a 'getValue(ProfileFragment, KProperty*>)' method. None of the following functions is suitable.
getValue(ProfileFragment, KProperty<*>) defined in by.kirich1409.viewbindingdelegate.ViewBindingProperty

Is it because I'm using databinding instead of viewBinding ?

Java usage

Can you provide how can we use this on a Java fragment?

thanks

Unexpected behavior on quick forward-back navigation in Fragments

Hello! Thanks for the great library and simple approach for viewBinding initialization.
I've discovered really annoying bug: if we will use fragment view bindings, try to replace current fragment with new fragment, and then quickly press back - our current fragment will not show all initialization data, which we will provide in it in onCreateView call.

This happens because we're calling handler.post { viewBinding = null } in ClearOnDestroyLifecycleObserver.onDestroy. method. Thus, if we happen to open next screen, and exit from it really fast, the viewBinding, that is accessed in onCreateView method will be this undestroyed binding.

Method call list will be such:

  1. Fragment B: onCreateView
  2. Fragment B: BackPressed
  3. Fragment A: onDestroyView
  4. Fragment A: onCreateView <-- invalid viewBinding here
  5. Fragment A: onStart
  6. Fragment A: onResume
  7. Fragment A: Post OnDestroy (ViewBinding cleared)

App crash on dialog

I'm using this library with this fragment:
https://github.com/kralonur/NotForgot/blob/37ea1a5627fea1d35ac99298786f7ab81f0430e5/app/src/main/java/com/example/notforgot/ui/task_create/category/CategoryDialog.kt

But I'm having crash with this code: (which is exactly code I'm using except using dialogViewBinding)

class CategoryDialog : DialogFragment() {
    private val viewModel by viewModels<CategoryViewModel>()
    private val binding by dialogViewBinding(LayoutCreateCategoryBinding::bind, R.id.category)
    private lateinit var dialog: AlertDialog

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        binding.lifecycleOwner = requireParentFragment().viewLifecycleOwner //Crash here
        binding.viewModel = viewModel // Even here if I dont set lifecycle owner

So basically I'm having crash whereever I use binding.

Logcat:

java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
        at androidx.fragment.app.Fragment.getViewLifecycleOwner(Fragment.java:328)
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getLifecycleOwner(FragmentViewBindings.kt:14)
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getLifecycleOwner(FragmentViewBindings.kt:10)
        at by.kirich1409.viewbindingdelegate.ViewBindingProperty.getValue(ViewBindingProperty.kt:30)
        at com.example.notforgot.ui.task_create.category.CategoryDialog.getBinding(Unknown Source:7)
        at com.example.notforgot.ui.task_create.category.CategoryDialog.onCreateDialog(CategoryDialog.kt:24)
        at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:419)
        at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1485)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2181)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2004)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1959)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:914)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7560)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
2020-10-24 01:41:09.200 14061-14061/com.example.notforgot I/Process: Sending signal. PID: 14061 SIG: 9

Not cleared binding for dialog fragment

I am create BottomSheetDialogFragment with using this libs
Example view binding
private val binding: BottomAccountDialogBinding by viewBinding(BottomAccountDialogBinding::bind)
In onCreateView returned view
inflater.inflate(R.layout.bottom_account_dialog, container, false)
I am open new fragment of dialog and after going back on dialog fragment using popBackStack, onCreateView method is called again but binding not cleared
I am see what onDestroyView is called but ViewBindingProperty not cleared my view binding
@MainThread public override fun clear() { mainHandler.post { viewBinding = null } }
This method not called for my BottomAccountDialogBinding
I'am see what DialogFragmentViewBindingProperty using fragment lifecycle but not view lifecycle
if (thisRef.showsDialog) { return thisRef } else { return thisRef.viewLifecycleOwner }
I'am tried change showsDialog parameter for my dialog fragment befor called binding in onViewCreated and in onDestroyView method and this is cleared binding else arises this problem
I think it's worth it return lifecycle for DialogFragmentViewBindingProperty

Support...

Do I need to call binding=null at onDestroy()

Execution failed for task ':app:minifyReleaseWithR8'

I am getting error while building apk for release.
I am using this version:

implementation("com.kirich1409.viewbindingpropertydelegate:viewbindingpropertydelegate:1.4.1")
implementation("com.kirich1409.viewbindingpropertydelegate:vbpd-noreflection:1.4.1")

The error:

Default interface methods are only supported starting with Android N (--min-api 24): Landroidx/lifecycle/DefaultLifecycleObserver;onCreate(Landroidx/lifecycle/LifecycleOwner;)V
Execution failed for task ':app:minifyReleaseWithR8'.
> com.android.tools.r8.CompilationFailedException: Compilation failed to complete, position: Landroidx/lifecycle/DefaultLifecycleObserver;onCreate(Landroidx/lifecycle/LifecycleOwner;)V

I have checked in library and I found that you are using in by.kirich1409.viewbindingdelegate.ViewBindingProperty.kt file:

@RestrictTo(LIBRARY_GROUP)
public abstract class LifecycleViewBindingProperty<in R : Any, T : ViewBinding>(
    private val viewBinder: (R) -> T
) : ViewBindingProperty<R, T> {

  /* ... */

    private inner class ClearOnDestroyLifecycleObserver : DefaultLifecycleObserver {

        @MainThread
        override fun onDestroy(owner: LifecycleOwner): Unit = clear()
    }

  /* ... */

}

Custom view with viewBinding doesn't show in preview AS

Hi. I have a trouble with my custom view where i use viewBinding delegate.

library version:
implementation 'com.kirich1409.viewbindingpropertydelegate:viewbindingpropertydelegate:1.4.1'

My view code

class ItemSelectorView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : LinearLayout(context, attributeSet, defStyleAttr) {
    private val binding by viewBinding<ViewItemSelectorBinding>(
        createMethod = CreateMethod.INFLATE
    )
    init {
        orientation = VERTICAL
        initAttrs(attributeSet)
    }
} 

XML for custom view:

< ?xml version="1.0" encoding="utf-8"?>
< merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:orientation="vertical"
    tools:parentTag="android.widget.LinearLayout">

<View/>

<TextView />

<TextView />

< /merge>

And when i add my view to layout - i have an "Failed to instantiate one of more classes"

java.lang.NoClassDefFoundError: Could not initialize package.presentation.custom.ItemSelectorView
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:413)
	at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:203)
	at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:161)
	at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:309)
	at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:417)
	at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:428)
	at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:332)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
	at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:1123)
	at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
	at android.view.LayoutInflater.rInflate(LayoutInflater.java:1097)
	at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:501)
	at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:328)
	at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:373)
	at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
	at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:713)
	at com.android.tools.idea.rendering.RenderTask.lambda$inflate$6(RenderTask.java:844)
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

What do i wrong?

Binding in an AlertDialog doesn't work

class MyDialogFragment : DialogFragment() {
    private val binding: MyDialogBinding by dialogViewBinding(R.id.my_dialog_container)

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = 
        AlertDialog.Builder(requireContext())
            .setView(R.layout.my_dialog)
            .create()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        binding.myButton.setOnClickListener { dismiss() }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_dialog_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Button!" />

</FrameLayout>

I don't get a crash anymore (I did in 1.2.2), but doing anything with the binding (like setting the onClickListener to the Button) has no effect.

checkIsMainThread

Hi, nice lib.
Isn't checkIsMainThread redundant? Android framework already has a lot of checks. You will got an exception if trying to touch views from another thread.

Consider next snippet:

binding.textView1.text = "blabla"
binding.textView3.text = "blabla"
binding.textView2.text = "blabla"

Looper.getMainLooper() contains synchronized block, seems like overhead for mentioned above case.

BUG ViewBinding crushed inside DialogFragment with AlertDialog

I've got crush Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView() when set view to dialog (setView(viewBinding.root))

supportFragmentManager?.let { updateDialog.showDialog(it) } //showDialog

Dialog

class SimpleDialog : BaseDialogFragment(0, null) {

    companion object {
        const val DEF_DIALOG_TAG = "GabiDialog"
        const val canBeCanceled = false
    }
    
    private val viewBinding: DialogGabiBinding by viewBinding(createMethod = CreateMethod.INFLATE)

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        isCancelable = canBeCanceled

        val dialog = AlertDialog.Builder(requireContext())
            .setView(viewBinding.root)
            .setCancelable(canBeCanceled)
            .create()

        initDialogView(dialog)

        return dialog
    }

    private fun initDialogView(dialog: AlertDialog) {
        viewBinding.dialogTitle.apply {}

        viewBinding.dialogContent.apply {}

        viewBinding.confirmBtn.apply {}

        viewBinding.cancelBtn.apply {}
    }

    fun showDialog(fragmentManager: FragmentManager, tag: String = DEF_DIALOG_TAG) {
        if (fragmentManager.findFragmentByTag(tag) != null)
            (fragmentManager.findFragmentByTag(tag) as? DialogFragment)
                ?.dismiss()
        
        show(fragmentManager, tag)
    }
    
}

BaseDialogFragment

abstract class BaseDialogFragment(
    @LayoutRes private val layoutRes: Int,
    private val onDismiss: (() -> Unit)? = null
): DialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Timber.d("Lifecycle - onCreate %s", this.javaClass.name)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return if (layoutRes != 0)
            inflater.inflate(layoutRes, container, false)
        else
            null
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Timber.d("Lifecycle - onViewCreated %s", this.javaClass.name)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog =  super.onCreateDialog(savedInstanceState)
        Timber.d("Lifecycle - onCreateDialog %s", this.javaClass.name)
        return dialog
    }

    override fun onStart() {
        super.onStart()
        Timber.d("Lifecycle - onStart() %s", this.javaClass.name)
    }


    override fun onStop() {
        super.onStop()
        Timber.d("Lifecycle - onStop() %s", this.javaClass.name)
    }

    override fun onResume() {
        super.onResume()
        Timber.d("Lifecycle - onResume() %s", this.javaClass.name)
    }

    override fun onPause() {
        super.onPause()
        Timber.d("Lifecycle - onPause() %s", this.javaClass.name)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Timber.d("Lifecycle - onDestroyView() %s", this.javaClass.name)
    }

    override fun onDestroy() {
        super.onDestroy()
        Timber.d("Lifecycle - onDestroy() %s", this.javaClass.name)
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onDismiss?.invoke()
    }

}

Invalid ViewBinding on quick forward-back navigation in Fragments

If the Fragment is put in the back stack and then immediately restored with FragmentManager.popBackStack(), ViewBinding still points to old view during onViewCreated.

Here is a sample project to reproduce.

I suppose this is the same bug as in #35, but it is still reproducible with Fragments 1.3.0 and ViewBindingPropertyDelegate 1.4.4. So, as you suggested, I'm opening a new issue.

Add support of RecyclerView.ViewHolder

The basic usage example:

class MyViewHolder(view) : RecyclerView.ViewHolder(view) {
    // Without reflection
    private val viewBinding by viewBinding(MyViewBinding::bind)

    // With reflection. itemView will be used as root for MyViewBinding
    private val viewBinding : MyViewBinding by viewBinding()
}

ViewBindingProperty can't be shared between classes

Hello, I've made the update to 1.2.0 but since then when I switch from a fragment to another fragment I get this error
I'm using databinding (not viewbinding) however I've enabled it in my gradle as in the README.

Here is my gradle:

buildFeatures {
        dataBinding = true
        viewBinding = true
    }

dependencies {
    implementation 'com.kirich1409.viewbindingpropertydelegate:viewbindingpropertydelegate:1.2.0'
    // To use only without reflection variants of viewBinding
    implementation 'com.kirich1409.viewbindingpropertydelegate:vbpd-noreflection:1.2.0'
}
java.lang.IllegalStateException: Instance of ViewBindingProperty can't be shared between classes
        at by.kirich1409.viewbindingdelegate.ViewBindingProperty.getValue(ViewBindingProperty.kt:29)
        at com.application.poc.ui.search.SearchFragment.getBinding(Unknown Source:7)
        at com.application.poc.ui.search.SearchFragment.onDestroyView(SearchFragment.kt:103)
        at androidx.fragment.app.Fragment.performDestroyView(Fragment.java:2909)
        at androidx.fragment.app.FragmentManager.destroyFragmentView(FragmentManager.java:1356)
        at androidx.fragment.app.FragmentManager.removeCancellationSignal(FragmentManager.java:742)
        at androidx.fragment.app.FragmentManager$2.onComplete(FragmentManager.java:370)
        at androidx.fragment.app.FragmentAnim$2$1.run(FragmentAnim.java:175)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

Here is the code:

class SearchFragment: Fragment(R.layout.fragment_search) {

    private val binding: FragmentSearchBinding by viewBinding(FragmentSearchBinding::bind)
    private lateinit var searchAdapter: SearchAdapter
    private val viewModel: SearchViewModel by lazy {
        ViewModelProvider(this).get(SearchViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        searchAdapter = SearchAdapter()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setHasOptionsMenu(true)
        binding.lifecycleOwner = this
        binding.rvSearchHistory.adapter = searchAdapter

        viewModel.termList.observe(viewLifecycleOwner, {
            it?.let {
                if(it is Resource.Success) searchAdapter.submitList(it.data.map { searchEntity ->
                    searchEntity.searchText
                })
            }
        })
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.rvSearchHistory.adapter = null
    }
}

ViewBinding stopped working with proguarded builds

When I run a release build I get the following exception:

Caused by: java.lang.NoSuchMethodException: com.action.consumerapp.databinding.ActivitySplashBinding.bind [class android.view.View]
   at java.lang.Class.getMethod(Class.java:2072)
   at java.lang.Class.getMethod(Class.java:1693)
   at d.a.a.j.a.<init>(ViewBindingCache.kt:97)
   at d.a.a.j.f.a(ViewBindingCache.kt:27)
   at d.a.a.g$a.a(ActivityViewBindings.kt:38)
   at d.a.a.g$a.invoke(Unknown Source:2)
   at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.f(ViewBindingProperty.kt:59)
   at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.a(ViewBindingProperty.kt:46)
   at com.action.consumerapp.feature.splash.SplashActivity.i(Unknown Source:7)

This occurs at 'com.github.kirich1409:viewbindingpropertydelegate:1.4.3' and 'com.github.kirich1409:viewbindingpropertydelegate:1.4.4'. This doesn't happen with 'com.github.kirich1409:viewbindingpropertydelegate:1.4.2' (or 'com.kirich1409.viewbindingpropertydelegate:viewbindingpropertydelegate:1.4.2').

Not inflating correctly when using CreateMethod.INFLATE

When I attempt to use your library on my Fragments it does not inflate correctly. The layout is squished in the top left corner of my screen. My standard code looks like this:

private var binding: FragmentTestBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentTestBinding.inflate(inflater, container, false)
        return binding?.root
    }

but it looks like your code, in the INFLATE enum, is making the container null. My guess is that this is what's causing the issue. Anyway my company currently extends the Fragment class so I'm not able to pass in the XML file into the Fragment as you seem to like doing in your examples.

I can't watch when i customview

private val binding: EdittextCustomViewBinding by viewBinding(CreateMethod.INFLATE)

init {
    addView(binding.root)
    initAttrs(context, attrs)
}

Screenshot_3

Crash after upgrading to 1.4.2

We use noreflection variant of the library and after upgrading to 1.4.2, the app is now crashing.

This is an example of how we've been using it:

class OnboardingContainerFragment : BaseFragment() {
    private val binding by viewBinding {
        OnboardingContainerFragmentBinding.inflate(layoutInflater)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View = binding.root

And this is the crash we're receiving since 1.4.2:

    java.lang.IllegalStateException: Fragment doesn't have view associated with it or the view has been destroyed
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getLifecycleOwner(FragmentViewBindings.kt:31)
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getLifecycleOwner(FragmentViewBindings.kt:26)
        at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue(ViewBindingProperty.kt:57)
        at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue(ViewBindingProperty.kt:45)
        at br.com.ifood.activity.OnboardingContainerFragment.getBinding(Unknown Source:7)
        at br.com.ifood.activity.OnboardingContainerFragment.onCreateView(OnboardingContainerFragment.kt:34)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2950)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:515)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2177)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2088)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3122)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3056)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:473)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1514)
        at android.app.Activity.performStart(Activity.java:7843)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3412)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2123)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7710)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

I'd like your help to understand if we're doing something wrong or if there's a bug on the library.

Thanks!

Crash in DialogFragment. ID does not reference a View inside this View

I am using this library 1.4.5 version.
With this function
public inline fun <F : Fragment, T : ViewBinding> Fragment.viewBinding( crossinline vbFactory: (View) -> T, @IdRes viewBindingRootId: Int )
And working in activity and fragment.
When using in DialogFragment.
The app crash when I try to use viewBinding instance in onViewCreated callback.
After some investigated, found the dialog contentView will be set in onActivityCreated which is called after onViewCreated.
But the delegate will get the view from dialog inside.

Is that a bug? Please give some suggestions, thanks.

java.lang.IllegalStateException

Version 1.4.1

java.lang.IllegalStateException: 
  at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.androidx.fragment.app.Fragment.getViewLifecycleOwner (:4)
                                                                   getLifecycleOwner
                                                                   getLifecycleOwner
  at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue (:1)
                                                                    getValue
  at my.app.base.WebFragment.getVb (Unknown Source:7)
  at my.app.base.WebFragment$onViewCreated$$inlined$with$lambda$2.my.app.base.WebFragment.access$getVb$p (:1)
                                                                                    onProgressChanged
  at Fa.d (chromium-TrichromeWebViewGoogle.apk-stable-410410183:3)
  at Cs.handleMessage (chromium-TrichromeWebViewGoogle.apk-stable-410410183:57)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:224)
  at android.app.ActivityThread.main (ActivityThread.java:7560)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:539)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:950)
class WebFragment : BaseFragment(R.layout.fragment_web) {
    private val vb by viewBinding(FragmentWebBinding::bind)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      with(vb.webview) {
            settings.javaScriptEnabled = true
            webViewClient = object : WebViewClient() {...}
            webChromeClient = object : WebChromeClient() {
                override fun onProgressChanged(view: WebView?, newProgress: Int) {
                    super.onProgressChanged(view, newProgress)
                    vb.progressView.root.isVisible = newProgress in 0..99
                }
            }
      }
    }
}

There is not issue for version 1.1.0

How to pass generic type to viewBindingDelegate

I am trying to pass a generic type to the viewBinding Delegate, but it says: Cannot use 'vb' as reified type parameter. Use a class instead. Is this even possible?

abstract class BaseEmailFragment<out vb: ViewDataBinding>(
    layout: Int,
) : Fragment(layout) {

    private val binding by viewBinding<vb>() // Cannot use 'vb' as reified type parameter. Use a class instead.
}

Need explanation behind the solution.

There are two popular articles on View Binding Delegates, 1st is https://medium.com/@Zhuinden/simple-one-liner-viewbinding-in-fragments-and-activities-with-kotlin-961430c6c07c and 2nd is yours. I have seen both implementation, there are some differences in the implementation. Being a developer of one such solution, you would be able to understand the difference better. So, how does you implementation differ from this https://gist.github.com/Zhuinden/ea3189198938bd16c03db628e084a4fa implementation? Also, I have have seen some comments which warn against using such implementation. So what are those things that anyone should keep in mind while using such implementation? I hope you would shed some light on this.
I have asked similar question on the other solution too! As, we can grow better as a community.
Thanks!

Add Lint check about wrong usage in DialogFragment

For DialogFragment you need to use special delegates dialogViewBinding, because viewBinding don't work correctly in all cases. Need to add rule that will analyze DialogFragment code and notify about replacement.

Make a separate artifacts for "reflection" and "general" approach

I see that the library have the following proguard rule:

https://github.com/kirich1409/ViewBindingPropertyDelegate/blob/48d2e6e561c322d9f02365db388dffa899c8805e/library/proguard-rules.pro#L1

It prevents on obfuscation *ViewBinding classes. If I don't use reflection in delegate I expect that all my classes will be obfuscated.

The proposal is to make separate artefacts:

  • viewbindingpropertydelegate - regular logic, without reflection under the hood
  • viewbindingpropertydelegate-reflection - additional extensions for reflection approach + keep rule for ViewBinding classes.

Also with two artefacts, it will be clear for everyone what kind of delegate better to use and etc.

Implementation of Fragment.onCreateView with BindingPropertyDelegate

Usual implementation approximately that way:

private var binding: ResultProfileBinding? = null

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View = ResultProfileBinding.inflate(inflater, container, false).also {
    binding = it
}.root

override fun onDestroyView() {
    super.onDestroyView()
    binding = null
} 

But with BindingPropertyDelegate it looks like:

private val binding by viewBinding { fragment ->
        ResultProfileBinding.bind(fragment.requireView())
    }

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_result_profile_binding, container, false)

As a result instead of using only one class ResultProfileBinding that encapsulate all layout info in one place, I have and ResultProfileBinding (with implicit ref to layout res) and explicit ref to layout res. I assume that there is a way to fetch ref to layout res from ResultProfileBinding static fields but I couldn't find it :(

Do you know that way? And how you usually implement onCreateView with BindingPropertyDelegate?

license is missing

i would like to use this lib in a commercial project.
but im not allowed to use a lib without a license.
if you agree, i would be happy if you add a apache or mit license as i could add the lib without a meeting.

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.