7

Edit - solution

When using view binding, a Java binding file is generated for each xml. The problem was that when you modify the xml, it doesn't regenerate the Java files. So, when I added an ID tag to the App_bar_main in activity_main.xml, I was getting an error message saying it can't find that tag not because it doesn't like it but because it was still using the older Java files. Invalidating the caches and restart didn't affect those generated java binding files neither.

The only way to regenerate the files was to delete them.

With the added ID, I just had to call appBarMain using its ID instead of trying to inflate its layout.

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
...
    private ActivityMainBinding mActivityMainBinding;
    private AppBarMainBinding mAppBarMainBinding;
...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mActivityMainBinding.getRoot());

        mAppBarMainBinding = mActivityMainBinding.appBarMain;
        setSupportActionBar(mAppBarMainBinding.toolbar);

        mAppBarMainBinding.fabCollapse.fab_collapse.setOnClickListener(view -> {
            Log.d(TAG, "Clicked fab_collapse");
        });
   }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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_main"
        android:id="@+id/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.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_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Thank you all for your contributions

Original

I'm trying to switch the findViewById calls in my app to the newly added ViewBinding but I'm having issues interacting with the views other than the one called in setContentView().

Is the way I'm inflating AppBarMainBinding wrong? or am I missing something else?

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
...
    private ActivityMainBinding mActivityMainBinding;
    private AppBarMainBinding mAppBarMainBinding;
...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mActivityMainBinding.getRoot());

        mAppBarMainBinding = AppBarMainBinding.inflate(getLayoutInflater());
        setSupportActionBar(mAppBarMainBinding.toolbar);

        mAppBarMainBinding.fabCollapse.fab_collapse.setOnClickListener(view -> {
            Log.d(TAG, "Clicked fab_collapse");
        });
   }
}

The activity_main.xml contains <include layout="@layout/app_bar_main" /> and a menu

app_bar_main.xml contains a toolbar and some action buttons

In this case, if i call setContentView(mActivityMainBinding.getRoot()), in the main activity's onCreat(), the app launches the activity_main layout and displays the action button and the toolbar placeholder but none of the buttons work. Clicking on the action button doesn't invoke its setOnClickListener and the toolbar is blank (it doesn't implement setSupportActionBar(toolbar))

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.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_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

app_bar_main.xml

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

<!-- Min api = 21
        Add: Screen capture  -->

<androidx.coordinatorlayout.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"
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" />

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/fab_collapsed_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    app:layout_dodgeInsetEdges="bottom">

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_collapse"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:backgroundTint="@android:color/holo_orange_dark"
        app:fabSize="mini"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:srcCompat="@android:drawable/arrow_up_float" />

</androidx.constraintlayout.widget.ConstraintLayout>



</androidx.constraintlayout.widget.ConstraintLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

Thanks

Reda Hammoud
  • 333
  • 3
  • 9

3 Answers3

4

You only need to set content view, then you can access appbar with mActivityMainBinding.appBarMain.

Sina
  • 2,683
  • 1
  • 13
  • 25
  • App_bar_main doesn't have an ID, I can't call it that way. I can't add an ID to it neither. – Reda Hammoud Oct 17 '19 at 23:55
  • 1
    @ Reda: You've used include tag and declared your included layout as app_bar_main. This is enough to access your needed layouts in the app bar like: mActivityMainBinding.appBarMain.toolbar – Sina Oct 18 '19 at 05:17
  • that gave me an error saying it can't find the symbol appBarMain – Reda Hammoud Oct 18 '19 at 10:29
  • Never mind, I just found out that each time I update the XML file, I need to delete the generated databinding files. Just deleted that folder, added the ID to the App_bar_main in activity_main.xml call and was able to call it that way. Thanks – Reda Hammoud Oct 18 '19 at 10:52
  • I just realized there is a problem with your layout. you have to wrap with a tag. I updated my answer. – Sina Oct 18 '19 at 10:54
  • With what? I think only the databinding requires you to wrap it. With view binding you can leave it as is – Reda Hammoud Oct 18 '19 at 11:07
  • Yeah you are right. I forgot your problem was in viewbinding. – Sina Oct 18 '19 at 11:42
  • Just tried today's gradle release and the issue was resolved; no need to delete the generated files anymore. Thanks again for your help – Reda Hammoud Oct 18 '19 at 12:13
  • Happy to hear that. Thanks for the info. – Sina Oct 18 '19 at 15:29
4

it is much more easier to give the included layout an id with view binding so

instead of

<include layout="@layout/content_main" />

just use

<include 
 android:id="@+id/contentmain"
layout="@layout/content_main" />

And the binding would be binding.contentmain

Frank
  • 2,738
  • 2
  • 14
  • 19
0

Can you try to use this

mAppBarMainBinding = DataBindingUtil.setContentView(this, R.layout.your_activity);

It work fine for me.

Duy Khanh Nguyen
  • 454
  • 3
  • 11
  • 1
    Thanks for the suggestion but isn't DataBindingUtil different from View Binding? https://developer.android.com/topic/libraries/view-binding – Reda Hammoud Oct 17 '19 at 17:06
  • Yes, the DataBindingUtil work the same way as ViewBinding and it's also able to bind data to view. I prefer to use that. – Duy Khanh Nguyen Oct 18 '19 at 02:01
  • Databinding and Viewbinding are two very different concepts and should not be confused. – Emil S. Aug 24 '22 at 08:58