it-swarm.com.ru

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

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

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все еще активен, хотя я извлек транзакцию из backstack. во всяком случае, поскольку я получил исключение, я думал, что у меня нет выбора, кроме Деактивируйте фрагмент, Итак, я сделал:

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

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

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

Java.lang.IllegalStateException: fragment already active

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

56
Leem.fin

Чтение источника 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 пакета для изменения его значений.

147
Assaf Gamliel

Попробуйте удалить предыдущий фрагмент перед добавлением нового: https://stackoverflow.com/a/6266144/969325

1
Warpzit

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

fragmentTransaction.remove(activeFragment);

Вы бы сделали commit () после remove () тоже.

fragmentTransaction.remove(activeFragment).commit();
1
Joshua

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

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();
                    }
                }
0
Krzysztof Dziuba

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

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

Подвести итоги,

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

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

0
Ali Nem

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

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

0
Jonathan

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

0
Zhangali Bidaibekov