Search code examples
androidkotlinandroid-fragmentsandroid-recyclerviewandroid-viewpager2

Fragment not using full height of screen, but only after coming back from another Activity


I have an Activity with a TabLayout, a ViewPager2 and a FragmentContainerView like this:

<RelativeLayout 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:orientation="vertical"
    android:theme="@style/AppTheme"
    tools:context="com.safirecctv.easyview.activities.main.MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">


        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/activity_main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/visiotech_red"
            app:popupTheme="@style/AppTheme" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/activity_main_tab_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/visiotech_red"
            app:tabIconTint="?attr/tabLayoutTabColor"
            app:tabIndicatorColor="?attr/colorSecondary" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/activity_main_view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/main_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/app_bar" />
</RelativeLayout>

When I first launch the Activity with its Fragment (I've reduced it to one tab and one fragment for the sake of simplicity), everything works as expected, the Fragment takes the whole screen. But when I come back from another Activity by calling:

mActivity?.finish()

The fragment loads well, but only takes half of the screen height. I've tried to inspect with Layout Inspector, but if I attach it before coming back, the app force closes, and if I attach it after (when the Fragment is loaded and only taking half of the screen height), then it recreates and works well again.

I am testing in a real device, not in the emulator.

This is my Fragment XML:

<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">

    <data>
        <variable name="viewModel" type="com.safirecctv.easyview.viewmodels.main.DeviceManagementViewModel"/>
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:orientation="vertical"
            android:id="@+id/list_view_devices"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?attr/listViewBackgroundColor"
            app:data="@{viewModel.devices}" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentBottom="true"
            android:layout_margin="16dp"
            android:src="@drawable/icon_plus"
            app:backgroundTint="@color/visiotech_red"
            app:tint="?attr/buttonTextColor"
            tools:ignore="ContentDescription" />
    </RelativeLayout>
</layout>

And this is the code behind:

package com.safirecctv.easyview.activities.add_edit_device.fragments

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.safirecctv.easyview.R
import com.safirecctv.easyview.databinding.ActivityAddEditDeviceIpddnsFragmentBinding
import com.safirecctv.easyview.viewmodels.add_edit_device.IpDdnsDeviceViewModel
import dagger.hilt.android.AndroidEntryPoint

/**
 * Fragment used to add or edit IP/DDNS devices to/from the database.
 * As of June, 2021, the following vendors support IP/DDNS login: Safire/Hikvision, XSecurity/Dahua, Uniview.
 */
@AndroidEntryPoint
class AddEditIPDDNSDeviceFragment : Fragment(R.layout.activity_add_edit_device_ipddns_fragment) {
    private val mViewModel: IpDdnsDeviceViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val binding = ActivityAddEditDeviceIpddnsFragmentBinding.bind(view)
        binding.apply {
            btnSaveDeviceIpDdns.setOnClickListener { trySaveDevice() }
            viewModel = mViewModel
            lifecycleOwner = viewLifecycleOwner
        }
    }
    //endregion

    //region Device methods
    private fun trySaveDevice() {
        //mViewModel.trySaveDevice()
        activity?.finish()
    }
    //endregion
}

Could it be related to the fact that I'm not calling onCreateView in the Fragment but instead delegating it to the constructor?

Thank you very much.

EDIT: I could open Layout Inspector finally, and this is what it shows: RecyclerViewImpl is taking the whole space but the FrameLayout inside it only takes like half of the screen: Screenshot of Layout Inspector


Solution

  • I finally found it. The problem was in the Activity's XML. Everything was inside AppBarLayout and that was causing the issue. I just left the MaterialToolbar inside AppBarLayout and the rest as a sibling, as explained in this post (in Spanish). Then everything started working as intended.