layout_content.xml
<layout>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
/>
</android.support.design.widget.AppBarLayout>
</layout>
layout_main.xml
<layout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/dl_main_drawer"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include layout="#layout/layout_content" android:id="#+id/content"/>
</android.support.v4.widget.DrawerLayout>
</layout>
MainActivity.java
LayoutMainBinding binding = DataBindingUtil.setContentView(this,R.layout.layout_main);
setSupportActionBar(binding.content.toolbar);
Android Studio intellisense check binding.content is ViewDataBinding obj
but build error 'cannot find symbol variable content'
Will this have any problem?
thx!
The layout activity_main.xml:
<layout>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/layout_content" android:id="#+id/content" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</layout>
generates ActivityMainBinding.java. In your MainActivity.java, you use the generated field for content in the setSupportActionBar argument:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
setSupportActionBar(binding.content.toolbar);
}
Normally a layout will generate public final fields for each of the Views with android:ids and Binding subclasses for each of the includes with IDs. In this case, the data binding system did not detect that the included content #layout/layout_content was a binding layout and thus didn't capture the Binding class for the include.
When a variable is bound to an include, the data binding system will use that to determine that the included layout is a binding layout. So, if your layout had this instead:
<include layout="#layout/layout_content"
android:id="#+id/content"
app:someVar="#{someVar}" />
You'd have gotten a content field with the type LayoutContentBinding. This does assume that someVar is declared in both activity_main.xml and layout_content.xml.
The error in Android Studio was pointing to the correct location, but it was difficult to understand. In the future, you can look for the generated binding class in your app/build directory. This may help you figure out what the error means.
I've filed a bug to fix the error -- we should be generating a public final field for the include with the ID.
Related
I have a nested included layouts in which i try to pass data binding.
the following code fails with the following error;
<?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:tools="http://schemas.android.com/tools">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/appBarMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include
layout="#layout/content_main"
android:id="#+id/contentMain"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
/.../ap_generated_sources/debug/out/com/example/.../databinding/ActivityMainBindingImpl.java:35: error: incompatible types: AppBarMainBinding cannot be converted to View
, (com.example...databinding.AppBarMainBinding) bindings[1]
^
if I remove the layout, the code compiles but then app:params added to include wont work. What am I missing? how to fix? Thanks
I had the same issue, and it was resolved after deleting the build folder in app directory and it built again without any error.
The problem is that the "content_main" layout not include flag or any layout inside it. Add it and make rebuild you that will fix the issue.
Hi I am trying use the data-bitindng with the navbar for do it I have the next code:
MapActivity.java
public class MapActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback, GoogleMap.OnMarkerClickListener{
private static final float INITIAL_MAP_ZOOM_LEVEL = 17;
private static final int INITIAL_REQUEST_CODE = 1;
private GoogleMap mMap;
private CameraUpdate cameraUpdate = null;
private MapViewModel mapViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMapBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_map);
mapViewModel = ViewModelProviders.of(this).get(MapViewModel.class);
binding.setMapViewModel(mapViewModel);
binding.setLifecycleOwner(this);
NavHeaderMapBinding headerBinding = NavHeaderMapBinding.inflate(getLayoutInflater());
headerBinding.setMapViewModel(mapViewModel);
binding.navView.addHeaderView(headerBinding.getRoot());
setDrawerLayout();
setNavigationView();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setMap();
setButtonEvents();
}
...
map_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="mapViewModel"
type="com.emtmadrid.cardiomadapp.map.MapViewModel" />
</data>
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_map"
app:menu="#menu/activity_map_drawer" />
</android.support.v4.widget.DrawerLayout>
</layout>
app_nav_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="mapViewModel"
type="com.emtmadrid.cardiomadapp.map.MapViewModel" />
</data>
<android.support.design.widget.CoordinatorLayout 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"
android:fitsSystemWindows="true"
tools:context=".map.MapActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/white"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
</layout>
When execute this code, I get the screen of the MapActivity but with 2 navbar, the first navbar databinding not work, and in the second navbar work perfectly.
How can solve this?
Any idea?
Thanks.
To solve the problem I dropped the following line in the app_nav_bar.xml
app:headerLayout="#layout/nav_header_map"
I'd like to challenge the accepted answer, because removing app:headerLayout appears counter-productive to me ...the data-binding is just missing the bind attribute on the include nodes:
<include
layout="#layout/app_bar_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:mapViewModel="#{mapViewModel}"/>
The same would go for this include, which should be moved outside of app_nav_bar.xml:
<include layout="#layout/content_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
bind:mapViewModel="#{mapViewModel}"/>
The result would be a working data-binding, where one only has to assign the MapViewModel once; the name-space for bind would be xmlns:bind="http://schemas.android.com/apk/res-auto".
When app_nav_bar.xml would only contain the AppBarLayout, it might be easier to handle; especially that include layout="#layout/content_map" appears quite confusing, in a file which is called app_nav_bar.xml. inflating the NavHeaderMapBinding is not required when having it already assigned with app:headerLayout - but the bind attribute is required, in order to have it bound.
Data-Binding Expressions: Includes also explains the combination of include & bind - which is generally less effort than inflating & binding several views by code - because inflating & binding the view once only works, when data-binding the include nodes properly with the layout resource XML. it's the actual beauty of data-binding, not having to bind all the includes by code.
Hello evreyone,
I get this error from my Layout XML: Multiple root error. So I tried a lot to fix it yet could not find any solution, please help me about it:
this is my code from file layout xml:
thanks a lot :)
You can have only one element in your XML that doesn't have a parent. By sparse information you gave us, you have at least two root elements: <RelativeLayout> and <android.support.v4.widget.DrawerLayout >.
To fix this error you just need to move </RelativeLayout> (closing tag) after DrawerLayout, that is to the end of the document. Or, probably better, move <android.support.v4.widget.DrawerLayout > to the beginning, enclosing other layouts.
However even if you do fix error you're getting this is not good implementation. You should read more about DrawerLayout.
you are getting Multiple root error in Layout because of
in Android every xml file there must be only one root layout
so try to add single parent to your layout
sample code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- add here your other controlls or layouts-->
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_home_class"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view_home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_home_class"
app:itemBackground="#android:color/transparent"
app:itemIconTint="#color/drawer_item"
app:itemTextColor="#color/drawer_item"
app:menu="#menu/activity_home_drawer" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
I have following very simple layout and wanted to switch to using data binding. Now I'm getting following error in my controller_main.xml:
Error:Execution failed for task ':app:dataBindingProcessLayoutsDebug_pro'.
****/ data binding error ****msg:[44 68 44 68 25] must include a layout
file:...\app\src\main\res\layout\controller_main.xml
****\ data binding error ****
Any ideas? The error says, the resource android:layout id in the include tag is missing (that's my interpretation of the error), but that's not true. Commenting out the include tag removes the error.
Does anyone see the problem?
controller_main.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
android:fitsSystemWindows="true"
android:background="?attr/main_background_color"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="#+id/rlContent"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
<include
android:layout_width="fill_parent"
android:layout_height="#dimen/tool_bar_top_padding"
android:id="#+id/stub_view_main_header_fixed"
android:layout="#layout/view_main_header_fixed"
app:elevation="0dp"/>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
</layout>
view_main_header_fixed.xml
<?xml version="1.0" encoding="utf-8"?>
<View
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/vStatusbarBackground"
android:layout_width="match_parent"
android:layout_height="#dimen/tool_bar_top_padding" />
You should use layout instead of android:layout:
<include
android:layout_width="fill_parent"
android:layout_height="#dimen/tool_bar_top_padding"
android:id="#+id/stub_view_main_header_fixed"
layout="#layout/view_main_header_fixed"
app:elevation="0dp"/>
I had the exact same error, but for a different reason.
I was using <include> opening tag and </include> closing tag instead of <include for opening and /> for closing. It's little strange, but anyway your question helped me find my mistake. Thanks.
I am trying to set the title of Toolbar in Android but the app crashes (null pointer exception). I have tried many stackoverflow same question but none seemed to work for me. I used the code below
toolbar = (Toolbar) findViewById(R.id.toolBarDataProvider);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Notice");
Logcat
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference at com.akapoor.kiittimetabletest1.Notice.onCreate(Notice.java:31)
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.akapoor.kiittimetabletest1.Notice">
<include
android:id="#+id/include"
layout="#layout/toolbar_data_provider"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10">
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9">
<TextView
android:id="#+id/tvServerText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="25dp"
android:textColor="#000000"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</ScrollView>
<Button
android:id="#+id/bServer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Refresh" />
</LinearLayout>
toolbar_data_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolBarDataProvider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
so you don't have Toolbar... maybe show us your code for style or xml layout for this Activity
edit:
maybe there is some id overwritting, when you using
<include
android:id="#+id/include"
this is your new id for your Toolbar (first view in included in separated files). try to use merge (wrap whole Toolbar) or just do not set new id in include
more HERE
In fact, you did not set your toolbar as a SupportActionctionBar, because you included it. To acces included layout you need to:
1) Get included layout:
View icludedLayout = findViewById(R.id.include);
2) Get Toolbar from it:
View toolbar = findViewById(R.id.toolBarDataProvider);
EDIT
If you haven't mistaken in question, and your tollbar xml file is named as Toolbar.xml you need to change include tag to:
<include
android:id="#+id/include"
layout="#layout/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
You must set the xml file name for layout attribute (Which in your case the xml file name is Toolbar)
EDITED
Replace this:
<include
android:id="#+id/include"
layout="#layout/toolbar_data_provider"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
With the following code (In this code, I set the id of include tag to toolBarDataProvider instead of include):
<include
android:id="#+id/toolBarDataProvider"
layout="#layout/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
And the Toolbar.XML file should contains the following code (The toolbar id attribute is not needed):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
Though setSupportActionBar you pass null parameter. Thus you toolbar is null. In this way we can make a conclusion that findViewById cannot find view with id toolbarDataProvider. I suggest you need to check validity of your id. Or provide information about your xml.
EDITED
So, as I said you don't have id toolbarDataProvider. When you use include tag you import view described in other xml, but you can override attributes to it. In your case you override id attribute from toolbarDataProvider to include. Try to change your code to see if it works correctly:
toolbar = (Toolbar) findViewById(R.id.include);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Notice");
This is a very very late answer but for anyone still looking for help on this question... assign your toolbar the id of include. This worked for me, also be sure to set your toolbar in styles to NoActionBar.
toolbar = (Toolbar) findViewById(R.id.include);