Access view binding in Fragment from Activity

6.3k views Asked by At

I am upgrading an application to remove all synthetics and use the new ViewBinding feature. So far everything works as long as you are inside of the class/layout you are accessing, but I have synthetic references to layout elements in my Main Activity.

In class Fragment:

    private var _binding: FragmentBinding? = null
    val binding get() = _binding!!
    private val compositeDisposable = CompositeDisposable()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        App.instance.getAppComponent().inject(this)
        _binding = FragmentBinding.inflate(inflater, container, false)
        return binding.root
    }

In MainActivity I have:

    private lateinit var mainBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(null)
        mainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mainBinding.root)
    }

I have methods for dialogs which use synthetics to dim layout elements in the Fragment. eg.

//textView on fragment layout.xml
textView?.alpha = someFloat

This works fine when synthetic, however I cannot get the new view binding to work based on Android's documention. How can I easily mimic the synthetic behavior with ViewBinding? So far it has increased the code by a large amount and does not work unless the Fragment's view has been created and has honestly made the code worse and harder to understand. I attempted to use bind off the the main activity layout root view but I got "view must have a tag" errors, and all layouts start with <layout>. Any help is appreciated.

2

There are 2 answers

2
Liong On

If you wanted to access a viewbinding in fragment from activity, the easy answer for it is you can't. Because you can't access any properties in fragment from activity.

Vice versa, you can access activity property from fragment. Make one of your property to be public, and access with requireActivity().propertiesInActivity, example:

In Activity:

lateinit var bind: ActivityYourBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityYourBinding.inflate(layoutInflater)
    ...
}

In Fragment (which this fragment parent is YourActivity):

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        ...
        var someFloat = 0 // fill with your number
        val yourActivity = requireActivity() as YourActivity
        yourActivity.bind.yourTextView.alpha = someFloat
        ...
}

Hope this can help anyone and solve their problem

0
rahat On

Since your question is abstract, I came up with the following

textView?.alpha = someFloat

would become

if your text view is in the fragment

binding.textView.alpha = someFloat

and in case it is in the activity

mainBinding.textView.alpha = someFloat