Страницы

Поиск по вопросам

четверг, 13 февраля 2020 г.

Передать значение переменной из Activity в Fragment

#java #android #android_fragment




Пытаюсь сделать расписание занятий, но не очень получается. 
Есть два Java Class-а: MainActivity и ContentFragment(содержащий фрагмент), сделал
выпадающее меню в котором есть два значения "Первая неделя" и "Вторая неделя", при
нажатии на которые текст во фрагментах должен меняться соответственно.

Я пытался просто передать значение переменной itemPosition 

public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    pos = itemPosition;
    Intent intent = new Intent(MainActivity.this, ContentFragment.class);
    intent.putExtra("pos", pos);
    return true; 


разными способами или просто получить её в ContentFragment классе 

MainActivity Main = new MainActivity(); 
int item = Main.pos;


Чтобы потом сравнивать её и писать соответствующий текст, если item = 0 - первой
недели, если = 1 - второй, но значение переменной так и не удалось получить. Оно постоянно
было = 0;

Вот и вопрос: как это реализовать? Или может есть до неприличия иной простой метод
решения моей задачи?
    


Ответы

Ответ 1



Предложу такой вариант решения Вашей задачи. В MainActivity Создаем интерфейс: interface MainActivityCommunicator{ void onWeekChanged(int numberOfWeek); } MainActivityCommunicator mSendToFragment; В методе onNavigationItemSelected добавляем строчку: public boolean onNavigationItemSelected(int itemPosition, long itemId) { ... mSendToFragment.onWeekChanged(itemPosition); ... } В ContentFragment Реализуем интерфейс MainActivityCommunicator public class ContentFragment extends ... implements MainActivity.MainActivityCommunicator{ ... @Override public void onWeekChanged(int numberOfWeek) { //Если выбранная неделя уже отображается, то return if(numberOfWeek == mCurrentSelectedWeek){ return; } //Тут меняем отображение недели } ... UPD: Указываем что данный фрагмент реализует данный интерфейс: @Override public void onAttach(Activity activity) { super.onAttach(activity); Context context = getActivity(); ((MainActivity) context).mSendToFragment = this; } Обnullяем ссылку на фрагмент когда он становится Detach: @Override public void onDetach() { super.onDetach(); Context context = getActivity(); ((MainActivity) context).mSendToFragment = null; }

Ответ 2



Можно использовать библиотеку EventBus и высылать событие смены недели из активити во фрагмент. В MainActivity просто высылаем соответствующий Event когда изменилась неделя public class MainActivity extends Activity { private void onWeekChange(int weekIndex) { EventBus().getDefault().post(new ChangeWeekEvent(weekIndex)); } } Во фрагменте обрабатываем следующим образом public class ContentFragment extends Fragment { public void onStart(){ EventBus.getDefault().register(this); //some code } public void onStop(){ EventBus.getDefault().unregister(this); //some code } //вызывается, когда из активити послали ивент public void onEvent(ChangeWeekEvent event){ //обрабатываем ивент } } Класс Event может выглядеть так: public class ChangeWeekEvent { private final int newWeek; //Другие поля public ChangeWeekEvent(int newWeek) { this.newWeek = newWeek; } }

Ответ 3



Я обычно использую для таких вещей адаптер FragmentPagerAdapter. public class MyActivity extends Activity { private MyAdapter myAdapter; private FragmentManager fm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_activity); pager = (ViewPager) findViewById(R.id.fragmentPager); fm = getSupportFragmentManager(); // Обработчик переключения между фрагментами ViewPager.SimpleOnPageChangeListener viewPagerListener = new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { super.onPageSelected(position); } }; pager.setOnPageChangeListener(viewPagerListener); // Класс, управляющий фрагментами myAdapter = new MyAdapter(fm); pager.setOffscreenPageLimit(2); pager.setAdapter(myAdapter ); } // Выбор пункта меню public boolean onNavigationItemSelected(int itemPosition, long itemId) { // В зависимости от выбранного пункта меню, мы можем передать любые свои данные в заданный фрагмент if (itemPosition == 0) { myAdapter.updateFragment(0); // Передаем данные в первый фрагмент (лучше завести именованные константы) } // и так далее... return true; } } В коде адаптера создаю нужное количество фрагментов. public class MyAdapter extends FragmentPagerAdapter { private Fragment[] fragments; public MyAdapter(FragmentManager fm) { super(fm); // Создаем нужное количество фрагментов (для индексации и доступа снаружи лучше завести публичные константы, чтобы не путаться в дальнейшем) fragments = new Fragment[2]; fragments[0] = new Fragment(); fragments[1] = new Fragment(); } @Override public Fragment getItem(int num) { if (num >= 0 && num < fragments.length) return fragments[num]; else return null; } @Override public int getCount() { return fragments.length; } /** * Обновить фрагмент * Дополнительными параметрами можно передать любые данные из активити */ public void updateFragment(int index) { fragments[index].updateData(); } } В дальнейшем любые данные можно передавать через новые методы адаптера. Но не стоит забывать о том, что в процессе работы фрагменты могут выгружаться из памяти, причем независимо от активити, поэтому надо предусмотреть случаи, когда фрагменты пересоздаются заново.

Комментариев нет:

Отправить комментарий