Принесите фрагмент к фронту (без фрагментации)

У меня есть три фрагмента F1 F2 F3 F4, все из которых доступны из боковой панели.

все четыре могут быть вызваны в любое время и в любом порядке,

Теперь я хочу, если F1 уже щелкнул (создал), а затем никогда больше не создавал F1, а только возвращал фрагмент F1 вперед с помощью диспетчера фрагментов. То же самое для всего остального фрагмента

Пока я пробовал это для каждого фрагмента в моем контейнере (ФРАГМЕНТНАЯ ДЕЯТЕЛЬНОСТЬ)

if (fragmentManager.findFragmentByTag("apps")==null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

Fragment newFragment = new CategoriesFragment();
transaction.replace(R.id.content_frame, newFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();   
} else{

}

If часть гарантирует, что NO фрагмент не будет воссоздан (если он уже создан) снова, но что я должен писать в части else, чтобы уже созданный фрагмент можно было вывести на передний план в View Hierarchy

Пожалуйста, помогите, я застрял на этом в течение 2 дней.

Ответ 1

Я бы поместил этот код в класс активности, который должен иметь FrameLayout с id R.id.fragment_container.

private Fragment1 F1;
private Fragment2 F2;
private Fragment3 F3;
private Fragment4 F4;       

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    F1 = new Fragment1();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F1).commit();
    F2 = new Fragment2();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F2).commit();
    F3 = new Fragment3();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F3).commit();
    F4 = new Fragment4();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F4).commit();

    //if needed show F1
    getSupportFragmentManager().beginTransaction().show(F1).commit();

}

И добавьте это для нажатия кнопки:

public void onBtnClick(View view){
    if(mShowF1){
        getSupportFragmentManager().beginTransaction().show(F1).commit();
        getSupportFragmentManager().beginTransaction().hide(F2).commit();
        getSupportFragmentManager().beginTransaction().hide(F3).commit();
        getSupportFragmentManager().beginTransaction().hide(F4).commit();
    }
    //...
}

На кнопках нажмите кнопку, чтобы отобразить, какой фрагмент вы хотите и скрыть.

ПРИМЕЧАНИЕ (@developer1011): Для использования после операции сохранить государственный вызов commitAllowingStateLoss (). Используйте с осторожностью, потому что фрагмент не восстанавливается с восстановлением активности.

Примечание: MainActivity должен реализовать OnFragmentInteractionListener для каждого фрагмента.

public class MainActivity extends FragmentActivity implements Fragment1.OnFragmentInteractionListener, Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener, Fragment4.OnFragmentInteractionListener {//..

    @Override
    public void onFragmentInteraction(Uri uri) {
        //
    }
}

Ответ 2

Получить фрагмент по тегу и заменить его в контейнере

else{
Fragment existingFragment = (CategoriesFragment)fragmentManager.findFragmentByTag("apps");
transaction.replace(R.id.content_frame,existingFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();
}

UPDATE: вы можете использовать фрагмент hide и show во избежание отдыха. Вместо использования "transaction.replace()"

fragmentTransaction.hide(<oldFragment>);
fragmentTransaction.show(<newFragment>);

Ответ 3

  • Используйте простой ArrayList<Fragment> для ваших фрагментов и добавьте их в порядке, чтобы вы знали, что get (0) получит F1, get (1) получит F2 и т.д.

  • Создайте фрагменты как одиночные. В каждом фрагменте добавьте статическое поле и метод:

     private static Fragment mMyInstance = null;
    
     public static Fragment newInstance() {
         if (mMyInstance == null) {
             mMyInstance = new F1();
         }
         return mMyInstance;
     }
    
  • Создайте фрагменты со статическим методом и добавьте их в ArrayList.

  • В каждом фрагменте добавьте команду setRetainInstance(true); к методу onCreate().

Теперь, когда вы добавляете фрагмент с помощью FragmentManager, onCreate() будет вызываться только в первый раз, но onCreateView() будет вызываться каждый раз. Вы хотите раздуть представление и подключить виджеты каждый раз, только если ваша активность была восстановлена ​​из-за изменения конфигурации. Но вы можете проверить что-то, что вы добавите, чтобы увидеть, было ли это в первый раз или нет, и reset виджетов в их предыдущем состоянии, если нет. Таким образом, вам понадобятся переменные-члены в ваших фрагментах, чтобы отслеживать их состояние. Переопределите onStop(), чтобы сохранить состояние и повторно применить его в onCreateView() после подключения виджетов.

Затем, когда нажата кнопка боковой панели, вы получаете Фрагмент, соответствующий этой кнопке, удалите предыдущий фрагмент и добавьте текущий с помощью FragmentManager (или просто используйте команду replace() вместо remove()/add()).

Ответ 4

Если вы используете Фрагмент поддержки, то этот статический метод выполняет задание.

    /**
 * Takes a Fragment TAG and tries to find the fragment in the manager if it exists and bring it to front.
 * if not, will return false;
 * @param manager
 * @param tag
 */
public static boolean resurfaceFragment(FragmentManager manager, String tag ){
    Fragment fragment = manager.findFragmentByTag(tag);
    FragmentTransaction transaction = manager.beginTransaction();
    if (fragment!=null){
        for (int i = 0; i < manager.getFragments().size(); i++) {
            Fragment f =  manager.getFragments().get(i);
            transaction.hide(f);

        }
        transaction.show(fragment).commit();
        return true;
    }

    return false;
}

Ответ 5

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

public static void attachFragment ( int fragmentHolderLayoutId, Fragment fragment, Context context, String tag ) {


    FragmentManager manager = ( (AppCompatActivity) context ).getSupportFragmentManager ();
    manager.findFragmentByTag ( tag );
    FragmentTransaction ft = manager.beginTransaction ();

    if (manager.findFragmentByTag ( tag ) == null) { // No fragment in backStack with same tag..
        ft.add ( fragmentHolderLayoutId, fragment, tag );
        ft.addToBackStack ( tag );
        ft.commit ();
    }
    else {
        ft.show ( manager.findFragmentByTag ( tag ) ).commit ();
    }
}