Подтвердить что ты не робот

Получено исключение: уже активирован фрагмент

У меня есть фрагмент;

MyFragment myFrag = new MyFragment();

Я помещаю данные пакета в этот фрагмент:

Bundle bundle = new Bundle(); 
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);

Затем я замените старый фрагмент на этот и положим на backstack:

//replace old fragment
fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag");
//put on backstack
fragmentTransaction.addToBackStack(null);
//commit & get transaction ID
int transId = fragmentTransaction.commit();

Позже я поп назад с указанным выше идентификатором транзакции (transId):

//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 

Позже я установил данные пакета в качестве аргумента снова для моего фрагмента (myFrag):

//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);

Как вы видите, мой код выше получил исключение Java.lang.IllegalStateException: fragment already active. Я не понимаю, почему myFrag все еще активен, хотя я вынул транзакцию из него., так или иначе, так как я получил исключение, я думал, что у меня нет выбор, но деактивировать фрагмент. Итак, я сделал:

Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);

Я не уверен, действительно ли мой код выше de-active, так как я не нашел, как деактивировать фрагмент.: (

После этого, когда я попытаюсь снова установить данные пакета в мой фрагмент myFrag, я все равно получаю ту же ошибку:

Java.lang.IllegalStateException: fragment already active

Кажется, что даже я удалил фрагмент, он все еще активен... Почему? Как деактивировать фрагмент?

4b9b3361

Ответ 1

Чтение источника setArguments (Bundle args) поможет вам понять:

/**
* Supply the construction arguments for this fragment.  This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment.  The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {

    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

Вы не можете использовать setArguments (Bundle args) снова в своем коде на том же Fragment. То, что вы хотите сделать, я думаю, это либо создать новый Fragment, и снова установить аргументы. Или вы можете использовать getArguments(), а затем использовать метод put для пакета, чтобы изменить его значения.

Ответ 2

Попробуйте удалить предыдущий фрагмент перед добавлением нового: fooobar.com/questions/108230/...

Ответ 3

remove() изменить статус фрагмента для деактификации. В вашем случае вы просто не вызывали commit() после удаления (..).

fragmentTransaction.remove(activeFragment);

Вы также выполняете commit() после удаления().

fragmentTransaction.remove(activeFragment).commit();

Ответ 4

Была та же проблема. Я добавлял фрагмент в backstack. И ошибка была в том, что я не вызывал popbackstack(). Использование popbackstack помогло мне

Ответ 5

Я столкнулся с той же проблемой на Xamarin.android. Здесь говорится в документации.

Это можно вызвать только до того, как фрагмент был прикреплен к его активности

Ответ 6

Просто вызовите общедоступный метод из фрагмента

if(userFragment==null){
                    userFragment = new UserFragment();
                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXTRA_CUSTOMER, result);
                    userFragment.setArguments(bundle);
                }else{
                    try {
                        Customer customer = new Customer();
                        customer.parseCustomer(new JSONObject(result));
                        userFragment.updateVeiw(customer);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

Ответ 7

Сначала я начинаю с описания того, почему это происходит, и затем я придумаю решение, которое я нашел рабочим...

Эта проблема возникает, когда Android удаляет фрагмент из стека, но заканчивается еще не с удалением. Чтобы проверить это, вы можете использовать метод isRemoving() для фрагмента. Если false, т.е. Фрагмент неактивен, вы можете продолжить настройку аргументов с помощью setArguments(bundle). В противном случае вы не можете устанавливать аргументы для уже активного фрагмента и можете только переопределять его, обращаясь к тем же аргументам, используя getArguments().putAll(bundle).

Подводя итог,

    if (myFrag.isRemoving()) {
        myFrag.getArguments().putAll(bundle);
    } else {
        myFrag.setArguments(bundle);
    }

Если вы хотите избежать этого, то есть сразу удалить фрагмент, чтобы не было активного фрагмента, вы можете использовать onBackPressed() в onBackStackChangedListener(), который установит isRemoving() в false.