2015-05-19 3 views
2

Так что в основном то, над чем я работаю, очень похоже на приложение Instagram, где есть несколько вкладок, и пользователи могут переключаться на любой без какой-либо задержки независимо от того, что происходит, например, обновления, перезагрузки и т. д. Он также использует кнопку «Назад», чтобы вернуться к предыдущей сохраненной вкладке.Отображение и скрытие фрагментов не происходит (не происходит) сразу после обновления SwipeRefreshLayout

Для этого я использовал FragmentManager с FragmentTransaction, чтобы показать и скрыть каждый фрагмент, который представляет каждую вкладку. Я не использовал replace или attach/detach, потому что они уничтожают иерархию просмотров предыдущей вкладки.

Мое выполнение работает довольно хорошо, за исключением того, что показ и скрытие фрагментов не совершены (я очень сомневаюсь, что это правильное слово, но до сих пор это то, как я понял поток.), Или не происходит сразу , когда SwipeRefreshLayout освежает фрагмент (который будет скрыт), который был добавлен к FragmentManager позже, чем тот, который показывает.

Мое исполнение соответствует таким правилам. Допустим, у нас есть 4 вкладки, а мой MainActivity показывает первую вкладку, скажем FirstFragment, и пользователь выбирает вторую вкладку, SecondFragment. Потому что SecondFragment ранее не был добавлен, я добавляю его в FragmentManager с помощью FragmentTransaction.add и спрятал FirstFragment с помощью FragmentTransaction.hide. Если пользователь выбирает первую вкладку снова, потому что FirstFragment был ранее добавлен в FragmentManager, он не добавляет, но только показать FirstFragment и просто скрыть SecondFragment. И выбор между этими двумя вкладками работает плавно.

Но когда пользователь «обновит» SecondFragment «s SwipeRefreshLayout и выбирает первую вкладку, FragmentTransaction ждёт SecondFragment» s обновления будет завершена и совершает (?) Фактическую сделку. Странная вещь заключается в том, что транзакция совершается немедленно наоборот, от FirstFragment обновление до SecondFragment.

Поскольку это происходит по порядку добавления к FragmentManager, я сомневаюсь, что порядок добавления каким-то образом влияет на стопку фрагментов, и может существовать что-то вроде приоритета потока пользовательского интерфейса, чтобы он принудительно выполнял транзакцию фрагмента после более поздней версии, добавлен интерфейс пользовательского интерфейса добавленного фрагмента. Но у меня просто не хватает подсказок для решения проблемы. Я пробовал прикреплять/отсоединять и возвращать вещи на FragmentTransaction, но не смог решить проблему. Я пробовал и FragmentTransaction.commit, и FragmentTransaction.commitAllowingStateLoss, но не решил проблему.

Это мой код MainActivity.

private ArrayList<Integer> mFragmentsStack; // This is simple psuedo-stack which only stores 
              // the order of fragments stack to collaborate 
              // when back button is pressed. 
private ArrayList<Fragment> mFragmentsList; 

@Override 
protected void onCreate() { 
    mFragmentsStack = new ArrayList<>(); 
    mFragmentsList = new ArrayList<>(); 
    mFragmentsList.add(FirstFragment.newInstance()); 
    mFragmentsList.add(SecondFragment.newInstance()); 
    mFragmentsList.add(ThirdFragment.newInstance()); 
    mFragmentsList.add(FourthFragment.newInstance()); 
    mMainTab = (MainTab) findViewById(R.id.main_tab); 
    mMainTab.setOnMainTabClickListener(this); 

    int currentTab = DEFAULT_TAB; 

    mFragmentsStack.add(currentTab); 
    getSupportFragmentManager().beginTransaction().add(R.id.main_frame_layout, 
      mFragmentsList.get(currentTab), String.valueOf(currentTab)).commit(); 
    mMainTab.setCurrentTab(currentTab); 
} 

// This is custom interface. 
@Override 
public void onTabClick(int oldPosition, int newPosition) { 
    if (oldPosition != newPosition) { 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 

     // First hide the old tab. 
     fragmentTransaction.hide(mFragmentsList.get(oldPosition)); 

     // Recalculate the fragment stack. 
     if (mFragmentsStack.contains(newPosition)) { 
      mFragmentsStack.remove((Integer) newPosition); 
     } 
     mFragmentsStack.add(newPosition); 

     // Add new fragment if it's not added before, or show new fragment which was already hidden. 
     Fragment fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(newPosition)); 
     if (fragment != null) { 
      fragmentTransaction.show(fragment); 
     } else { 
      fragmentTransaction.add(R.id.main_frame_layout, mFragmentsList.get(newPosition), 
        String.valueOf(newPosition)); 
     } 

     // Commit the transaction. 
     fragmentTransaction.commitAllowingStateLoss(); 
    } 
} 

// It mimics the tab behavior of Instagram Android application. 
@Override 
public void onBackPressed() { 
    // If there's only one fragment on stack, super.onBackPressed. 
    // If it's not, then hide the current fragment and show the previous fragment. 
    int lastIndexOfFragmentsStack = mFragmentsStack.size() - 1; 
    if (lastIndexOfFragmentsStack - 1 >= 0) { 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.hide(mFragmentsList.get(mFragmentsStack.get(lastIndexOfFragmentsStack))); 
     fragmentTransaction.show(mFragmentsList.get(mFragmentsStack.get(lastIndexOfFragmentsStack - 1))); 
     fragmentTransaction.commitAllowingStateLoss(); 
     mMainTab.setCurrentTab(mFragmentsStack.get(lastIndexOfFragmentsStack - 1)); 
     mFragmentsStack.remove(lastIndexOfFragmentsStack); 
    } else { 
     super.onBackPressed(); 
    } 
} 
+0

Вы пытались дозвониться executePendingTransactions()? Попробуйте это и посмотрите, поможет ли это. – dora

+0

@dora Я добавил 'executePendingTransactions()' после фиксации, но он не работает. Мне интересно, правильно ли это место, потому что то, что говорит документ, похоже, является ответом на мою ситуацию. –

ответ

3

Только что столкнулся с той же проблемой с разницей - я переключаю фрагменты на кнопки панели инструментов. мне удалось избавиться от перекрывающихся фрагментов переопределения onHiddenChanged:

@Override 
public void onHiddenChanged(boolean hidden) { 
    super.onHiddenChanged(hidden); 
    if (hidden) { 
     yourSwipeRefreshLayout.setRefreshing(false); 
    } 
} 
+0

Я думал об этом, 'setRefreshing' - false при изменении вкладок, но мне не понравилась идея заставить состояние пользовательского интерфейса отличаться от того, что происходит на самом деле. Однако я не могу найти обходное решение, так что это сделает самую близкую работу. Спасибо. –

+0

Сохраните мой день! Я использую бесконечный просмотр пейджера с SwipeRefreshLayout. Индикатор обновления не будет отображаться снова, если я продолжу прокрутку вправо до одного и того же вида во второй раз => ex 0,1,2,0,1,2. setRefreshing (false) в destroyItem(), и он работает !!! – JackWu

Смежные вопросы