Search code examples
javaandroidandroid-fragmentsandroid-databinding

Toolbar disappears while replacing fragment when Data Binding in Android


I'm replacing my main activity's layout with fragments in order to keep the same navigation menu. However I've done data binding to fragment_home.xml and now the toolbar no longer shows up, even though I still switch to the intended fragment. After some debugging, I believe it has something to do with the setContentView in HomeFragment.java.

Any ideas?

Here's my 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity"
    tools:openDrawer="start">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="#000"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <FrameLayout
            android:id="@+id/frag_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <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"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/side_navbar"
        app:itemTextColor="@color/black"
        app:itemIconTint="@color/black"/>

</androidx.drawerlayout.widget.DrawerLayout>

Replacing frame layout with the fragment

getSupportFragmentManager().beginTransaction().replace(R.id.frag_container, new HomeFragment()).commit(); ```

And the fragment_home.xml

<?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"
    tools:context=".HomeFragment">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/viewCities"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:padding="4dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
</layout>

And finally the HomeFragment.java

public class HomeFragment extends Fragment {
    private CityViewModel cityViewModel;
    private RetrofitAdapter retrofitAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        View view = inflater.inflate(R.layout.fragment_home, container, false);

        FragmentHomeBinding activityMainBinding =
                DataBindingUtil.setContentView(getActivity(), R.layout.fragment_home);

        RecyclerView recyclerView = activityMainBinding.viewCities;
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setHasFixedSize(true);

        cityViewModel = new ViewModelProvider(requireActivity()).get(CityViewModel.class);

        retrofitAdapter = new RetrofitAdapter();
        recyclerView.setAdapter(retrofitAdapter);

        return view;
    }
}

Solution

  • You do not have to set the content view again from the fragment. From the HomeFragnent for using the data-binding just do something as follows.

    FragmentHomeBinding binding; // declare the binding variable
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        binding = DataBindingUtil
                .inflate(inflater, R.layout.fragment_home, container, false);
    
        /* FragmentHomeBinding activityMainBinding =
                DataBindingUtil.setContentView(getActivity(), R.layout.fragment_home); */ 
    
        RecyclerView recyclerView = binding.viewCities; // use the binding here
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setHasFixedSize(true);
    
        cityViewModel = new ViewModelProvider(requireActivity()).get(CityViewModel.class);
    
        retrofitAdapter = new RetrofitAdapter();
        recyclerView.setAdapter(retrofitAdapter);
    
        return binding.getRoot();
    }