片段未使用全屏高度,但仅在从另一个 Activity 返回后才使用
Fragment not using full height of screen, but only after coming back from another Activity
我有一个 Activity
和一个 TabLayout
,一个 ViewPager2
和一个 FragmentContainerView
,像这样:
<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>
当我第一次启动 Activity
及其 Fragment
时(为了简单起见,我将其缩减为一个选项卡和一个片段),一切都按预期进行,Fragment
占据整个屏幕。但是当我通过调用从另一个 Activity
回来时:
mActivity?.finish()
片段加载良好,但只占屏幕高度的一半。我尝试使用 Layout Inspector 检查,但如果我在返回之前附加它,应用程序强制关闭,如果我在之后附加它(当 Fragment
加载并且只占屏幕高度的一半时),然后它重新创建并再次运行良好。
我是在真实设备中测试,而不是在模拟器中。
这是我的 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>
这是背后的代码:
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
}
这可能与我没有在 Fragment 中调用 onCreateView
而是将其委托给构造函数有关吗?
非常感谢。
编辑:我终于可以打开 Layout Inspector,这就是它显示的内容:RecyclerViewImpl
占据了整个 space 但其中的 FrameLayout
只占据了一半屏幕:
终于找到了。问题出在 Activity
的 XML 中。一切都在 AppBarLayout
里面,这就是导致问题的原因。我只是将 MaterialToolbar
留在 AppBarLayout
中,其余的作为兄弟姐妹,如 this post (in Spanish) 中所述。然后一切开始按预期工作。
我有一个 Activity
和一个 TabLayout
,一个 ViewPager2
和一个 FragmentContainerView
,像这样:
<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>
当我第一次启动 Activity
及其 Fragment
时(为了简单起见,我将其缩减为一个选项卡和一个片段),一切都按预期进行,Fragment
占据整个屏幕。但是当我通过调用从另一个 Activity
回来时:
mActivity?.finish()
片段加载良好,但只占屏幕高度的一半。我尝试使用 Layout Inspector 检查,但如果我在返回之前附加它,应用程序强制关闭,如果我在之后附加它(当 Fragment
加载并且只占屏幕高度的一半时),然后它重新创建并再次运行良好。
我是在真实设备中测试,而不是在模拟器中。
这是我的 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>
这是背后的代码:
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
}
这可能与我没有在 Fragment 中调用 onCreateView
而是将其委托给构造函数有关吗?
非常感谢。
编辑:我终于可以打开 Layout Inspector,这就是它显示的内容:RecyclerViewImpl
占据了整个 space 但其中的 FrameLayout
只占据了一半屏幕:
终于找到了。问题出在 Activity
的 XML 中。一切都在 AppBarLayout
里面,这就是导致问题的原因。我只是将 MaterialToolbar
留在 AppBarLayout
中,其余的作为兄弟姐妹,如 this post (in Spanish) 中所述。然后一切开始按预期工作。