FragmentTabHost在配置更改(旋转)后随机变为空白

时间:2019-05-06 21:59:15

标签: android android-fragments fragment-tab-host

我在应用程序中遇到了令人沮丧的故障。

我的活动中有一个FragmentTabHost。 此选项卡托管者托管5个片段,每个片段都可以正确渲染。

现在,诀窍在于,当我旋转屏幕时,有时无法渲染片段。 该选项卡小部件仍在渲染并且可以单击,但是不显示与该片段相对应的视图。

下面是一个示例。 请注意,我在realtabcontent FrameLayout上放置了红色背景:

  1. 一切正常 enter image description here

  2. 旋转屏幕:屏幕随机变为部分空白 enter image description here

  3. 切换到其他选项卡将执行相关片段的OnCreate / OnCreateView,但不会显示任何内容 enter image description here

  4. 切换回第一个屏幕甚至不再显示“片段”按钮 enter image description here

请注意: -第一次旋转时,仍然显示一个按钮(它属于应渲染的片段)。 -触发错误后,我可以切换到其他标签。其他选项卡已正确加载(注意操作栏已更改),但FrameLayout中未呈现任何内容 -如果我回到第一个标签,则仍无法显示仍在显示的按钮

还请注意一个细节:即使正确设置了Reddot的代码,该选项卡的Reddot也消失了。就像选项卡宿主没有响应绘图请求一样。

以下是显示红点的代码:

    public void showReddotForTab(int tabIndx, Boolean showFlag){
        try {
            if (tabIndx < mTabHost.getTabWidget().getTabCount()) {
                RelativeLayout tabRootView         = (RelativeLayout) mTabHost.getTabWidget().getChildTabViewAt(tabIndx);
                WhovaNotificationBadge notifBadge  = tabRootView.findViewById(R.id.notif_badge);

                if (showFlag) {
                    notifBadge.setVisibility(View.VISIBLE);
                    notifBadge.setLabel(null);
                }
                else {
                    notifBadge.setVisibility(View.GONE);
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }

这是包含FragmentTabHost的活动的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="0dp"
                android:layout_height="0dp" />

            <FrameLayout
                android:id="@+id/realtabcontent"
                android:background="@color/red"
                android:layout_width="fill_parent"
                android:layout_height="0dp"
                android:layout_weight="1" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="2px"
                android:background="@color/separate_gray"/>

            <TabWidget
                android:id="@android:id/tabs"
                android:orientation="horizontal"
                android:background="@color/new_whova_tab_bg"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:paddingTop="6dp"
                android:layout_weight="0"/>

        </LinearLayout>

    </androidx.fragment.app.FragmentTabHost>


    <TextView
        android:id="@+id/text_network"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="40dp"
        android:layout_alignParentTop="true"
        android:background="@color/orange"
        android:text="@string/network_off_indicator_msg"
        android:visibility="gone"
        android:textColor="@color/white"
        android:gravity="center"/>

</RelativeLayout>

这是设置Tabhost的代码

        mTabHost = findViewById(android.R.id.tabhost);
        mTabHost.setOnTabChangedListener(tabId -> {
           ...
        })

        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
        mTabHost.getTabWidget().setDividerDrawable(null);

        //! simplified below, but the code is simlar to it
        //! spec is basically TabHost.TabSpec spec = mTabHost.newTabSpec("someID").setImageResource(...).setIndicator(...).setContent(tag -> findViewById(R.id.realtabcontent));
        mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
        mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
        mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
        mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
        mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);

1 个答案:

答案 0 :(得分:0)

找到了解决方法,但是我不知道是什么原因。

我的操作栏是一个包含AppCompatSpinner的工具栏。 微调框仅用于图片中显示的标签,并且已设置setOnItemSelectedListener

旋转屏幕时,将调用侦听器(不知道为什么,因为初始选择是在设置侦听器之前完成的,之后没有选择。

无论哪种方式,有时在调用此侦听器时,从DB加载的数据仍在后台处理。奇怪的是,一旦完成,我们将刷新用户界面,但它保持空白,其他选项卡也会受到影响。 我怀疑侦听器的调用方式有问题,它阻止了其他UI事件的处理,但不确定。

当我在帖子中设置侦听器时,问题消失了

spinner.post(() -> {
  spinner.setOnItemSelectedListener(...)
})