View Binding - How do I get a binding for included layouts?
In case of:
- Include with generic layout (not merge node), we need to assign ID to included part, this way in binding we will have access to included sub part
<include
android:id="@+id/your_id"
layout="@layout/some_layout" />
This way in your activity code:
private lateinit var exampleBinding: ActivityExampleBinding //activity_example.xml layout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
setContentView(exampleBinding.root)
//we will be able to access included layouts view like this
val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}
- Include with merge block in external layout. We can't add ID to it because merge block is not a view.
Let's say we have such eternal merge layout (merge_layout.xm):
<?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"
tools:showIn="@layout/activity_example">
<TextView
android:id="@+id/some_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World" />
</merge>
To properly bind such merge layout we need to:
In your activity code:
private lateinit var exampleBinding: ActivityExampleBinding //activity_example.xml layout
private lateinit var mergeBinding: MergeLayoutBinding //merge_layout.xml layout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
//we need to bind the root layout with our binder for external layout
mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
setContentView(exampleBinding.root)
//we will be able to access included in merge layout views like this
val mergedView: View = mergeBinding.someView
//[...]
}
How to use View Binding with Included Views?
Let's suppose that the layout in your question is activity_main.xml
. The generated view binding class for it is ActivityMainBinding
. Similarly, for item_header.xml
, the generated view binding is ItemHeaderBinding
.
If we pretend that item_header.xml
has a TextView
named @+id/foo
, then you wind up with this chunk of Kotlin:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val mainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mainBinding.root)
mainBinding.myHeader.foo.text = "this is a test"
}
}
So, the ActivityMainBinding
object should have a property with the android:id
that you gave to the <include>
— myHeader
in this case. That should be an ItemHeaderBinding
, as view binding appears to set up the nested binding object for the <include>
. Since myHeader
is an ItemHeaderBinding
, you can then reference widgets on it just as you would if you directly inflated ItemHeaderBinding
yourself.
Note that view binding appears to convert lower_snake_case
into lowerCamelCase
, so the my_header
ID turns into myHeader
in terms of the generated code.
View binding with include layout not working
I do nothing on it and it just works automatically. I surely did clean, rebuild, restart Android studio... something at that time but not working. Maybe link another layout in another class would trigger something just fix it under the hood cause I set aside this problem and keep going.
ViewBinding - Included Layout Binding Resulting in Unresolved Reference
If you're using Android Studio 3.6.0 sometimes gradle plugin fails to generate ViewBinding fields for included layouts. Please update to Android Studio 3.6.1 and gradle plugin version to 3.6.1.
How to use View Binding with Included Views in Java?
I have resolved the problem.
Original item_header.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:background="@android:color/transparent">
<TextView
android:id="@+id/foo"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
I removed id of framelayout and the error was soon gone.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:background="@android:color/transparent">
<TextView
android:id="@+id/foo"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
Be careful about using id while using view binding.
How to include an Android layout but also access its elements in binding?
Two things are required in order to use ViewBinding with an included layout.
<merge>
is not supported
The documentation only covers Data Binding, and not View Binding, but it does appear to be applicable to both. See https://developer.android.com/topic/libraries/data-binding/expressions#includes
Data binding doesn't support include as a direct child of a merge element.
In other words, the layout must have a real, concrete view as its root element. The following is supported:
<LinearLayout ...>
<TextView ... />
<TextView ... />
</LinearLayout>
But a layout with a <merge>
root is not supported:
<merge ...>
<TextView ... />
<TextView ... />
</merge>
The <include>
tag must specify an ID
It is, in general, possible to include a layout without explicitly specifying an ID. View Binding does not support this:
<include layout="@layout/included_layout"/>
Even if the included layout has an ID on its root element, it is still not supported. Instead, you must explicitly specify the ID on the <include>
tag:
<include
android:id="@+id/some_id"
layout="@layout/included_layout"/>
Once both of these conditions are satisfied, your generated binding for the outer layout will include a reference to the binding of the included layout. Let's say our two files are outer_layout.xml
and included_layout.xml
. Then these two files would be generated:
OuterLayoutBinding.java
IncludedLayoutBinding.java
And you could reference the included views like this:
val outerBinding = OuterLayoutBinding.inflate(layoutInflater)
val innerBinding = binding.someId // uses the id specified on the include tag
val innerView = innerBinding.viewPagerTop
Or, for short:
val binding = OuterLayoutBinding.inflate(layoutInflater)
val innerView = binding.someId.viewPagerTop
ViewBinding - How to set visibility for include layout in ViewBinding?
When we give <include>
an id it overrides the id of root layout that we included. In your case, layout_provinces
is overriding <RelativeLayout
's select_province
. So when you access the relative layout it gives you an error because it is no longer there.
What you can do is remove the id of relative layout and only give id to include and access the root layout that you included through the getRoot()
method like below.
Java
binding.selectProvince.getRoot().setVisibility(View.GONE)
Kotlin
binding.selectProvince.root.visibility = View.GONE
the getRoot()
method in View Binding returns the topmost view of the given layout in your case it's the RelativeLayout
.
DataBindingUtil bind layout from include
To use DataBinding in for fragment in android, use following way->
Create ->
private FragmentYourVideosBinding binding;
private View view;
Then use - >
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_your_videos, container, false);
view = binding.getRoot();
return view;
To access the FragmentBindinding just type FragmentBinding then you will see your Fragment Binding layout name in dropdownlist. Is described in above link you can read from there.
Firstly wrap your all child layouts by layout tag as below. You can copy the code its same as your code.
<?xml version = "1.0" encoding = "utf-8" ?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/tools" >
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<view.TouchyWebView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="@+id/content_view" >
</view.TouchyWebView>
<include
android:id="@+id/view_list"
layout="@layout/fragment_list"
android:layout_width="match_parent"
android:layout_height="596dp"
app:layout_constraintTop_toBottomOf="@+id/content_view"
tools:layout_editor_absoluteX="-9dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Related Topics
Nested Fragments Disappear During Transition Animation
Custom Translucent Android Actionbar
Progress Bar While Loading Image Using Glide
Differencebetween Sendstickybroadcast and Sendbroadcast in Android
Achartengine - Can't Figure How to Use Dates as X Axis - the File I Save Is Empty
Sliding Navigation Drawer Not Handling Clicks on Menu Items Android
How to Hide One Item in an Android Spinner
Add a New Item to Recyclerview Programmatically
What Are the Overheads of Using Autoincrement for SQLite on Android
Getting Null Device Id While Registering to Gcm
How to Allocate These Folders in Another Place
Read Contents of a Url in Android
Android Design Support Library Expandable Floating Action Button(Fab) Menu