Как полностью уничтожить фрагмент? [Дубликат]

Вместо того, чтобы бросать код на вас, есть два понятия, которые являются ключом к пониманию того, как JS обрабатывает обратные вызовы и асинхронность. (это даже слово?)

Модель цикла события и параллелизма

Есть три вещи, о которых вам нужно знать; Очередь; цикл события и стек

. В широких упрощенных терминах цикл событий подобен диспетчеру проекта, он постоянно прослушивает любые функции, которые хотят запускать и взаимодействовать между очереди и стека.

while (queue.waitForMessage()) {
   queue.processNextMessage();
}

Как только он получает сообщение для запуска чего-то, он добавляет его в очередь. Очередь - это список вещей, которые ждут выполнения (например, ваш запрос AJAX). Представьте себе это так:

 1. call foo.com/api/bar using foobarFunc
 2. Go perform an infinite loop
 ... and so on

Когда одно из этих сообщений будет исполнено, оно выталкивает сообщение из очереди и создает стек, стек - это все, что нужно выполнить JS для выполнения инструкции в сообщение. Таким образом, в нашем примере ему говорят позвонить foobarFunc

function foobarFunc (var) {
  console.log(anotherFunction(var));
}

. Так что все, что foobarFunc должно выполнить (в нашем случае anotherFunction), будет вставлено в стек. исполняемый, а затем забытый - цикл события затем переместится на следующую вещь в очереди (или прослушивает сообщения)

. Главное здесь - порядок выполнения. Это

КОГДА что-то будет запущено

Когда вы совершаете вызов с использованием AJAX для внешней стороны или выполняете любой асинхронный код (например, setTimeout), Javascript зависит от ответ, прежде чем он сможет продолжить.

Большой вопрос, когда он получит ответ? Ответ в том, что мы не знаем, поэтому цикл событий ждет, когда это сообщение скажет: «Эй, забери меня». Если JS просто ждал этого сообщения синхронно, ваше приложение замерзнет, ​​и оно сосать. Таким образом, JS продолжает выполнение следующего элемента в очереди, ожидая, пока сообщение не будет добавлено обратно в очередь.

Вот почему с асинхронной функциональностью мы используем вещи, называемые обратными вызовами. Это похоже на обещание буквально. Как и в I , обещание что-то вернуть в какой-то момент jQuery использует специальные обратные вызовы, называемые deffered.done deffered.fail и deffered.always (среди других). Вы можете увидеть их все здесь

Итак, вам нужно передать функцию, которая в какой-то момент будет выполнена с переданными ей данными.

Поскольку обратный вызов не выполняется немедленно, но в более позднее время важно передать ссылку на функцию, которую она не выполнила. поэтому

function foo(bla) {
  console.log(bla)
}

, поэтому большую часть времени (но не всегда) вы пройдете foo не foo()

. Надеюсь, это будет иметь смысл. Когда вы сталкиваетесь с такими вещами, которые кажутся запутанными, я настоятельно рекомендую полностью прочитать документацию, чтобы хотя бы понять ее. Это сделает вас намного лучшим разработчиком.

196
задан Graham Borland 28 February 2014 в 16:14
поделиться

9 ответов

Я не понимаю, что делать в Df, когда «OK» нажата, чтобы удалить фрагменты Df, Cf и Bf?

Шаг # 1 : Дайте Df сказать D "yo! Мы получили ОК нажмите!" путем вызова метода либо по самой операции, либо по экземпляру интерфейса, предоставленному активностью.

Шаг # 2: У D удалите фрагменты с помощью FragmentManager.

Хозяйственная деятельность (D) - это та, которая знает, какие другие фрагменты в действии (в отличие от других видов деятельности). Следовательно, события с фрагментами, которые могут повлиять на фрагмент-микс, должны быть распространены на активность, что приведет к соответствующим ходам оркестровки.

52
ответ дан CommonsWare 24 August 2018 в 06:48
поделиться

Вы должны позволить Управлению заниматься добавлением и удалением фрагментов, как говорит CommonsWare, использовать прослушиватель. Вот пример:

public class MyActivity extends FragmentActivity implements SuicidalFragmentListener {

    // onCreate etc

    @Override
    public void onFragmentSuicide(String tag) {
        // Check tag if you do this with more than one fragmen, then:
        getSupportFragmentManager().popBackStack();
    }
}

public interface SuicidalFragmentListener {
    void onFragmentSuicide(String tag);
}

public class MyFragment extends Fragment {

    // onCreateView etc

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
           suicideListener = (SuicidalFragmentListener) activity;
        } catch (ClassCastException e) {
           throw new RuntimeException(getActivity().getClass().getSimpleName() + " must implement the suicide listener to use this fragment", e);
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Attach the close listener to whatever action on the fragment you want
        addSuicideTouchListener();
    }

    private void addSuicideTouchListener() {
        getView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              suicideListener.onFragmentSuicide(getTag());
            }
        });
    }
}
31
ответ дан Blundell 24 August 2018 в 06:48
поделиться

Вы можете использовать подход ниже, он отлично работает:

getActivity().getSupportFragmentManager().popBackStack();
243
ответ дан Carsten 24 August 2018 в 06:48
поделиться

OnCreate:

//Add comment fragment
            container = FindViewById<FrameLayout>(Resource.Id.frmAttachPicture);
            mPictureFragment = new fmtAttachPicture();

            var trans = SupportFragmentManager.BeginTransaction();
            trans.Add(container.Id, mPictureFragment, "fmtPicture");
            trans.Show(mPictureFragment); trans.Commit();

Вот как я скрываю фрагмент в событии click 1

//Close fragment
    var trans = SupportFragmentManager.BeginTransaction();
    trans.Hide(mPictureFragment);
    trans.AddToBackStack(null);
    trans.Commit();

Затем показывает его обратно int event 2

var trans = SupportFragmentManager.BeginTransaction();
            trans.Show(mPictureFragment); trans.Commit();
0
ответ дан CodeSi 24 August 2018 в 06:48
поделиться

В Activity / AppCompatActivity:

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        // if you want to handle DrawerLayout
        mDrawerLayout.closeDrawer(GravityCompat.START);
    } else {
        if (getFragmentManager().getBackStackEntryCount() == 0) {
            super.onBackPressed();
        } else {
            getFragmentManager().popBackStack();
        }
    }
}

, а затем вызовите фрагмент:

getActivity().onBackPressed();

или как указано в других ответах, вызовите это в фрагмент:

getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
13
ответ дан Codeversed 24 August 2018 в 06:48
поделиться

Если вам нужно сбрасывать четвертый фрагмент из истории backstack в первый, используйте теги !!!

Когда вы добавляете первый фрагмент, вы должны использовать что-то вроде этого:

getFragmentManager.beginTransaction.addToBackStack ("A"). add (R.id.container, FragmentA) .commit ()

или

getFragmentManager.beginTransaction.addToBackStack ("A ") .replace (R.id.container, FragmentA) .commit ()

И если вы хотите показать фрагменты B, C и D, вы используете это:

getFragmentManager.beginTransaction .addToBackStack ("B"). replace (R.id.container, FragmentB, "B"). commit ()

и другие буквы ....

Чтобы вернуться к Фрагмент A, просто вызовите popBackStack (0, «A»), да, используйте флаг, который вы указали при его добавлении, и обратите внимание, что он должен быть тем же самым флажком в команде addToBackStack, а не тот, который используется в команде replace или add .

Добро пожаловать;)

1
ответ дан Diego Ramírez 24 August 2018 в 06:48
поделиться

Я создаю простой метод для этого

popBackStack(getSupportFragmentManager());

. Поместите его в мой класс ActivityUtils

public static void popBackStack(FragmentManager manager){
        FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
        manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

. Он отлично работает, получайте удовольствие!

3
ответ дан EliaszKubala 24 August 2018 в 06:48
поделиться

Хотя это может быть не самый лучший подход, ближайший эквивалент, я могу думать, что это работает с библиотекой поддержки / совместимости

getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

или

getActivity().getFragmentManager().beginTransaction().remove(this).commit();

в противном случае .

Кроме того, вы можете использовать backstack и всплывать. Однако имейте в виду, что фрагмент, возможно, не находится в задней части (в зависимости от фрагментации, который получил его там.), Или это может быть не последний, который попал в стек, поэтому выталкивание стека может удалить неправильный ...

287
ответ дан Manfred Moser 24 August 2018 в 06:48
поделиться

Посмотрите, удовлетворяются ли ваши потребности с помощью DialogFragment. DialogFragment имеет метод увольнения (). На мой взгляд, гораздо более чистым.

3
ответ дан Vasudev 24 August 2018 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: