Фрагментное общение: какой подход лучше?
Я работал над связью между несколькими фрагментами в стеке действий. Я выяснил 2 способа сделать это.
- Через интерфейсы
Через комплект поставки
Bundle bundle = new Bundle(); bundle.putBoolean("Status",trur); Fragment fragment = getFragmentManager().findFragmentByTag(bottomfragment.class.getName()); if(fragment!=null) { fragment.setArguments(bundle); }
2-й подход мне показался легким. Так как Google рекомендует 1-й подход
Может кто-нибудь помочь мне с проблемами, с которыми я могу столкнуться, следуя второму подходу
3 ответа
Вы смешиваете оба пути. 1. Сквозные интерфейсы - это если вы хотите общаться от фрагмента к действию или от фрагмента к фрагменту (посредством действия). 2. Установить аргумент - это если вы хотите передать аргументы при запуске фрагмента. Вы можете вызывать методы фрагмента, используя экземпляр, который вы получаете из фрагмента id/tag.
Попробуйте связать два фрагмента следующим образом:
1) Создайте интерфейс следующим образом:
public interface FragmentChangeListener {
void changeFragment(Fragment fragment);
}
2) Обновите MainActivity так:
public class MainActivity extends AppCompatActivity implements FragmentChangeListener
{
//Activity code
------
@Override
public void changeFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction tr = fm.beginTransaction();
tr.replace(R.id.frame_container, fragment);
tr.commitAllowingStateLoss();
}
}
3) Создать первый фрагмент:
public class FirstFragment extends Fragment
{
// call another freagment like this
//in your oncreateview method:
SecondFragment
Bundle b = new Bundle();
b.putSerializable(SELECTED_ITEM, true);
SecondFragment second = SecondFragment.newInstance(b);
FragmentChangeListener fc = (FragmentChangeListener) getActivity();
fc.changeFragment(second);
}
4) Второй фрагмент:
public class SecondFragment extends Fragment
{
public static SecondFragment newInstance(Bundle bundle) {
SecondFragment fragment = new SecondFragment();
if (bundle != null)
fragment.setArguments(bundle);
return fragment;
}
//another fragment related code
//In your OncreateView like this:
if (getArguments() != null)
boolean temp = getArguments().getBoolean(IntentParameter.SELECTED_ITEM);
}
Надеюсь, это объяснение поможет вам:)
Аргумент (Bundle
) должны быть переданы Fragment
только изначально (когда Fragment
объект создается по умолчанию конструктором). призвание setArguments
метод уже добавлен Fragment
вызовет IllegalStateException
, Увидеть тело setArguments
метод:
public void setArguments(Bundle args) {
if (mIndex >= 0 && isStateSaved()) {
throw new IllegalStateException("Fragment already active and state has been saved");
}
mArguments = args;
}
Если вы хотите что-то изменить в Fragment
От Fragment
B:
а) Получить объект А внутри Б, используя
getFragmentManager().findFragmentByTag("FRAGMENT_A_TAG");
Или же
getFragmentManager().findFragmentById(FRAGMENT_A_CONTAINER_ID);
Приведите возвращенный объект к A и вызовите соответствующий метод для него. (Это самый простой способ, но после него A и B становятся сильно связанными);
б) В качестве альтернативы, вы можете написать упомянутую логику внутри метода Activity
, который содержит эти 2 Fragment
s, получить ссылку на это Activity
внутри B с помощью getContext()
приведен к контейнеру Activity
и вызовите упомянутый метод на нем (Это убивает возможность многократного использования, потому что, если вы хотите иметь A и B на другом Activity
, Кастинг getContext()
вызовет ClassCastException
);
в) лучший способ общения между Fragment
s создать interface
, реализовать контейнер Activity
этим interface
, получите ссылку на это interface
внутри B и вызвать соответствующий метод на нем. (С помощью этого интерфейса вы можете реализовать столько действий, сколько захотите, поэтому этот подход можно использовать повторно, а A и B слабо связаны).