FragmentTabHost случайно исчезает после изменения конфигурации (ротация) - PullRequest
0 голосов
/ 07 мая 2019

Я столкнулся с разочаровывающим сбоем в своем приложении.

У меня есть 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, выполняется правильно.Как будто хост вкладок не отвечает на запросы рисования.

Вот код, отвечающий за отображение 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>

Вот код, устанавливающий вкладку

        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 голосов
/ 07 мая 2019

Нашел, как ее решить, но я понятия не имею, в чем причина.

Моя панель действий - это панель инструментов, содержащая AppCompatSpinner. Вращатель используется только для вкладки, показанной на рисунках, и имеет setOnItemSelectedListener.

При повороте экрана вызывается слушатель (не знаю почему, потому что первоначальный выбор сделан до настройки слушателя, а потом выбора не было.

В любом случае, иногда, когда вызывается этот слушатель, данные, загруженные из БД, все еще обрабатываются в фоновом режиме. Странно то, что, как только это будет сделано, мы обновим пользовательский интерфейс, но он останется пустым, и другие вкладки будут затронуты. Я подозреваю, что в способе вызова слушателя что-то не так, и он блокирует обработку других событий пользовательского интерфейса, но не уверен.

Когда я устанавливаю слушателя в сообщении, проблема исчезает

spinner.post(() -> {
  spinner.setOnItemSelectedListener(...)
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...