setUserVisibleHint()називається іноді раніше, onCreateView() а іноді після чого викликає неприємності.
Для подолання цього потрібно перевірити метод isResumed()всередині setUserVisibleHint(). Але в цьому випадку я зрозумів, що setUserVisibleHint()викликається, лише якщо фрагмент відновлений і видимий, НЕ під час створення.
Отже, якщо ви хочете щось оновити, коли є фрагмент visible, поставте свою функцію оновлення і в, onCreate()і в setUserVisibleHint():
@Override
public View onCreateView(...){
...
myUIUpdate();
...
}
....
@Override
public void setUserVisibleHint(boolean visible){
super.setUserVisibleHint(visible);
if (visible && isResumed()){
myUIUpdate();
}
}
ОНОВЛЕННЯ: І все-таки я зрозумів, що myUIUpdate()дзвонять іноді двічі, причина полягає в тому, що якщо у вас є 3 вкладки, і цей код знаходиться на 2-й вкладці, коли ви вперше відкриваєте першу вкладку, 2-я вкладка також створюється, навіть її не видно, і myUIUpdate()вона називається. Потім, коли ви переходите на другу вкладку, myUIUpdate()з if (visible && isResumed())виклику, і, як результат, ви myUIUpdate()можете викликати двічі за секунду.
Інша проблема полягає !visibleв тому, що вони setUserVisibleHintназиваються як 1), коли ви виходите з екрана фрагмента, так і 2) перед його створенням, коли ви переходите на екран фрагмента вперше.
Рішення:
private boolean fragmentResume=false;
private boolean fragmentVisible=false;
private boolean fragmentOnCreated=false;
...
@Override
public View onCreateView(...){
...
//Initialize variables
if (!fragmentResume && fragmentVisible){ //only when first time fragment is created
myUIUpdate();
}
...
}
@Override
public void setUserVisibleHint(boolean visible){
super.setUserVisibleHint(visible);
if (visible && isResumed()){ // only at fragment screen is resumed
fragmentResume=true;
fragmentVisible=false;
fragmentOnCreated=true;
myUIUpdate();
}else if (visible){ // only at fragment onCreated
fragmentResume=false;
fragmentVisible=true;
fragmentOnCreated=true;
}
else if(!visible && fragmentOnCreated){// only when you go out of fragment screen
fragmentVisible=false;
fragmentResume=false;
}
}
Пояснення:
fragmentResume, fragmentVisible: Переконайтеся, що myUIUpdate()в onCreateView()викликається лише тоді, коли фрагмент створений і видимий, а не під час резюме. Він також вирішує проблему, коли ви перебуваєте на першій вкладці, друга вкладка створюється, навіть якщо її не видно. Це вирішує це і перевіряє, чи відображається екран фрагмента, коли onCreate.
fragmentOnCreated: Переконайтеся, що фрагмент не є видимим і не викликається при першому створенні фрагмента. Тож тепер це, якщо пункт викликається лише тоді, коли ви проведете з фрагмента.
Оновлення
Ви можете ввести весь цей код у такий BaseFragmentкод, як цей метод та замінити.