Да кажем, че имам Activity
само с FrameLayout
(Опитах и с новия FragmentContainerView
), така че ще заредя Fragments
на него. Да приемем, че имам два фрагмента: fragA и fragB, първо ще заредя fragA и с бутон, присъстващ в този фрагмент, < em>заменете го с fragB.
Дефинирах функция на моя Activity
, за да мога да заредя нов Fragment
в контейнера:
public void loadFragment(Fragment fragment) {
FragmentTransaction fragTrans = getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null);
fragTrans.commit();
}
И ще извикам това от fragA, за да отиде до fragB. Дотук добре, всичко работи добре. Всъщност проблемът, с който се сблъсквам, не е във функционирането, е, че не ми харесва времето за зареждане на fragB, отнема около 2 секунди и бих искал да покажа зареждане на потребителя, но не мога да го постигна.
Първото нещо, което опитах, е да добавя gone ProgressBar
към оформлението на дейността, където е контейнерът. След това моята loadFragment
функция първо ще зададе тази лента на прогреса видима и след това ще извърши фрагментната транзакция и всеки фрагмент ще скрие (изчезнал) този изглед, преди да излезе от метода onCreateView
. Но проблемът е, че потребителят никога не вижда това ProgressBar
, все едно основният потребителски интерфейс е замразен, докато изобразява оформлението на fragB и следователно не актуализира потребителския интерфейс, правейки този прогресбар безполезен. Дори виждам някои пропуснати кадри в LogCat около 50 кадъра.
И двата фрагмента нямат логика, само onCreateView
имплементиран, където оформлението е раздуто. Мога да забележа, че ако променя оформлението на fragB на по-просто, то се зарежда моментално, така че предполагам, че проблемът е свързан с времето, необходимо за изобразяване на оформлението. Това тежко оформление е наистина голяма форма с много TextInputLayout
с TextInputEditText
и MaterialSpinner
(от GitHub).
Знам, че може би мога да опростя оформлението, но бих искал да знам как мога да покажа зареждане по време на изобразяване. Например, виждал съм някои приложения да зареждат някакъв вид думи изглед по време на зареждане и след това да го заменят с реални данни.
Едно нещо, което опитах, е да заредя фиктивно оформление с ProgressBar
в средата и в метода onCreateView
да публикувам Handler
, за да раздуя истинско оформление в същия контейнер в фона, като този:
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 към него, за да мога да разбера кой е истинският фрагмент, който искам да покажа. Този междинен фрагмент няма да бъде добавен към задния стек.
Как решавате този тип проблеми?
Handler
и премахване на всички изгледи в метода onDestroyView. Но ми изглежда грозно - person sebasira   schedule 04.04.2020