Фрагмент уже активен - при попытке 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);
}
}