Допустим, у меня есть Activity
только с FrameLayout
( Я также попробую с новым FragmentContainerView
), поэтому я буду загружать Fragments
на нем. Давайте предположим, что у меня есть два фрагмента: fragA и fragB , я сначала загружу fragA и с помощью кнопки, присутствующей в этом фрагменте, заменяем это с fragB .
Я определил функцию на моем Activity
, чтобы я мог загрузить новый Fragment
на контейнер:
public void loadFragment(Fragment fragment) {
FragmentTransaction fragTrans = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null);
fragTrans.commit();
}
И я назову это от fragA до go до fragB . Пока все хорошо, все работает отлично. На самом деле проблема, с которой я сталкиваюсь, заключается не в функционировании, а в том, что мне не нравится время загрузки fragB , оно занимает около 2se c, и я хотел бы отобразить загрузку в пользователь, но я не могу этого добиться.
Первое, что я попробую, это добавить ушел ProgressBar
в макет действия, где находится контейнер. Тогда моя loadFragment
функция сначала установит видимый этот progressBar, а затем выполнит транзакцию фрагмента, и каждый фрагмент будет скрывать ( исчез ) это представление перед выходом из метода onCreateView
. Но проблема в том, что пользователь никогда не видит этот ProgressBar
, это похоже на то, что основной пользовательский интерфейс зависает при рендеринге макета fragB и, следовательно, не обновляет пользовательский интерфейс, делая этот progressBar бесполезным. Я даже вижу пропущенных кадров в LogCat около 50 кадров.
Оба фрагмента не имеют лог c, только onCreateView
реализован там, где раздувается макет. Я могу заметить, что если я изменю макет fragB на более простой, он загружается мгновенно, поэтому я предполагаю, что проблема связана со временем, которое требуется для визуализации макета. Этот тяжелый макет - действительно большая форма с большим количеством TextInputLayout
с TextInputEditText
и MaterialSpinner
(от GitHub).
Я знаю, что, возможно, могу упростить макет, но я хотел бы знать, как я могу отобразить загрузку при рендеринге. Например, я видел, как некоторые приложения загружают какой-то dummy-view во время загрузки, а затем заменяют его реальными данными.
Одна вещь, которую я пробовал, это загрузить * 1060 макет * dummy с ProgressBar
в середине и в методе onCreateView
опубликуйте Handler
, чтобы накачать real макет на тот же контейнер в фоновом режиме, например:
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_dummy, container, false);
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
@Override
public void run() {
container.removeAllViews();
View realView = inflater.inflate(R.layout.fragment_real, container);
}
});
}
Эта работа вроде бы приятна, так как просмотр приятен, но при переходе назад макет fragB остается видимым в качестве фона других фрагментов. Я не тестировал его, но, возможно, я смогу позвонить container.removeAllViews();
перед выходом из фрагмента, и он будет работать, но все равно мне кажется, что это обходной путь, а не решение.
И еще я не пробовал потому что, возможно, это избыточное уничтожение, это иметь промежуточный или , загружающий фрагмент, и загружать его всегда до реального фрагмента, и я передам Intent Extra для него, чтобы я мог сказать, что реальный фрагмент, который я хочу показать. Этот промежуточный фрагмент не будет добавлен в backstack.
Как вы решаете такие проблемы?