Фрагмент уже активен - при попытке setArguments

Я использую пример в приведенной ниже ссылке

http://android-er.blogspot.in/2013/04/handle-onlistitemclick-of-listfragment.html

Здесь у меня есть два класса, которые расширяют фрагмент фрагмента и другие расширяющиеся фрагменты. Теперь я передаю объект для детализации фрагмента следующим образом:

* from ListFragment *

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);

        Bundle bundle = new Bundle();
        bundle.putSerializable(BUNDLE_KEY, obj);// passing this object

        detailFragment.setArguments(bundle);
        detailFragment.setUpLayout();// update the UI
} 

Теперь в классе Фрагмент, который я получаю, основной целью является обновление пользовательского интерфейса фрагмента на основе элемента, выбранного в фрагменте списка, это причина, по которой я отправляю объект

Bundle b = getArguments();
b.getSerializable(BUNDLE_KEY);

Теперь на выбранном элементе сказано: "Фрагмент уже активен".

В чем проблема? что я делаю неправильно?

Ответы

Ответ 1

Другое решение - создать пустой конструктор для вашего фрагмента.

public Detailfragment() {
    super();
    // Just to be an empty Bundle. You can use this later with getArguments().set...
    setArguments(new Bundle());
}

а в методе onListItemClick вы используете этот пакет:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);

    // Update the keys.
    detailFragment.getArguments().putSerializable(BUNDLE_KEY, obj);// passing this object

    detailFragment.setUpLayout();// update the UI
} 

Теперь вы можете вызвать метод getArguments() в методе setUpLayout().

Ответ 2

В официальном справочнике по разработке Android:

public void setArguments (Bundle args). Поставьте аргументы построения для этого фрагмента. Это может быть вызвано только до того, как фрагмент был присоединен к его активности; то есть вы должны вызвать его сразу же после создания фрагмента. Аргументы, приведенные здесь, будут сохраняться через уничтожение фрагментов и создание.

Ваш фрагмент уже прикреплен к его действию я предлагаю вам использовать свой собственный метод, вам не нужны setArguments!

создайте собственные аргументы setUIArguments (Bundle args) внутри класса фрагмента и обновите интерфейс фрагмента внутри этого метода

Вы вызовете этот метод следующим образом:

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);

        Bundle bundle = new Bundle();
        bundle.putSerializable(BUNDLE_KEY, obj);// passing this object

        detailFragment.setUIArguments(bundle); /* your new method */
} 

в вашем классе фрагментов

public void setUIArguments(Bundle args) {
    getActivity().runOnUiThread(new Runnable() {
        public void run() {
            /* do your UI stuffs */
        }
    }
}

Ответ 3

Вы можете проверить, есть ли уже аргументы, и если да, просто добавьте/обновите их.

private static void initFrag(Fragment frag, Bundle args) {
    if (frag.getArguments() == null) {
        frag.setArguments(args);
    } else {
        //Consider explicitly clearing arguments here
        frag.getArguments().putAll(args);
    }
}

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

Ответ 4

Эта глобальная переменная:

private FragmentManager fragmentmanager;
private FragmentTransaction fragmenttransaction;

Этот код помещен в ваш "Фрагмент списка" onCreate() Activity:

fragmenttransaction = fragmentmanager.beginTransaction();
fragmenttransaction.replace(detailFragmentID, detailFragment, "test");
fragmenttransaction.addToBackStack(null);
fragmenttransaction.commit();

Это событие щелчка Drawerlistitem:

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {

    Bundle bundle = new Bundle();
    fragmenttransaction = fragmentmanager.beginTransaction();

        if(fragmentmanager.findFragmentById("test") != null) {
            fragmenttransaction.remove(fragmentmanager.findFragmentByTag("test"));
        }     

   Detailfragment detailFragment =  (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);

       bundle.putSerializable(BUNDLE_KEY, obj);// passing this object

       detailFragment.setArguments(bundle);
       fragmenttransaction.replace(detailFragmentID, detailFragment, "test");
       fragmenttransaction.addToBackStack(null);
       fragmenttransaction.commit();    
} 

Теперь расширяем код фрагмента:

Bundle b = getArguments();
b.getSerializable(BUNDLE_KEY);

Ответ 5

Общедоступный метод фрагмента диалога

   public void setBundle(final Bundle bundle) {
        final Bundle arguments = getArguments();
        arguments.clear();
        arguments.putAll(bundle);
   }

Показать или обновить фрагмент диалога

   public void showMessageDialogue(final String tag, final Bundle bundle) {
        final Fragment fragment = mFragmentManager.findFragmentByTag(tag);
        if (fragment != null && fragment instanceof MessageDialogueFragment) {
            ((MessageDialogueFragment) fragment).setBundle(bundle);
         } else {
            final MessageDialogueFragment messageDialogueFragment = new MessageDialogueFragment();
            messageDialogueFragment.setArguments(bundle);
            messageDialogueFragment.show(mFragmentManager, tag);
         } 
   }