Передача данных из Activity в Fragment ViewPager2
Всем привет! Пытаюсь передать данные из MainActivity в один из фрагментов ViewPager2.
В MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
fragment1 = new Fragment1();
Bundle bundle = new Bundle();
bundle.putInt("1", 1);
fragment1.setArguments(bundle);
}
В Fragment1:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment1, container, false);
Bundle bundle = this.getArguments();
if (bundle != null)
{
int i = bundle.getInt("1", 0);
Log.d(Constants.LOG_TAG, "" + i);
}
return view;
}
bundle всегда null. Задача в том, чтобы при загрузке MainActivity данные отправлялись во фрагменты и при последующем их перелистывании через ViewPager2 отображались корректно. Судя по циклу жизни Fragment1, метод onCreateView создаётся когда пользователь перелистывает на него. Как правильно можно передавать данные в Fragment1?
UPD:
ViewPager2 инициализируется в onCreate MainActivity:
viewPager = findViewById(R.id.viewPager);
pagerAdapter = new MainPagerAdapter(this);
viewPager.setAdapter(pagerAdapter);
С помощью BottomNavigationView реализован переход между фрагментами ViewPager2:
bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener()
{
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item)
{
switch (item.getItemId())
{
case R.id.nav1:
viewPager.setCurrentItem(0);
return true;
case R.id.nav2:
viewPager.setCurrentItem(1);
return true;
case R.id.nav3:
viewPager.setCurrentItem(2);
return true;
default:
return false;
}
}
});
Здесь же создаётся fragment1 = new Fragment1(); и бандл.
Код адаптера:
public class MainPagerAdapter extends FragmentStateAdapter
{
public MainPagerAdapter(@NonNull FragmentActivity fragmentActivity)
{
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position)
{
switch (position)
{
case 0:
return new Fragment1();
case 1:
return new Fragment2();
default:
return new Fragment3();
}
}
@Override
public int getItemCount()
{
return 3;
}
}
После загрузки MainActivity хочу передать данные в фрагменты, а не создавать их каждый раз заново. В ViewPager для этих целей используется FragmentPagerAdapter.
Есть ли аналог в ViewPager2?
Ответы (2 шт):
Есть несколько путей:
Вы можете в вашей
Activityподготовить список фрагментов с бандлами и всеми данными и в вашMainPagerAdapterпередать этот список. Соответственно в методеpublic Fragment createFragment(int position) { return fragments.get(position); }вы не создаете новый фрагмент как у вас в коде, а просто берете его экземпляр из списка
fragmentsкоторый вы предварительно создали вActivityи положили (например через конструктор или метод set-er).Второй путь вы можете создавать готовый список нужных вам аргументов в
Activityи так же класть в ваш адаптер, и класть эти аргументы при создании фрагментов все в том же методеcreateFragment. Хотя по сути это те же яйца только в профиль.В целом можно создать в ваших фрагментах какой-то метод кастомный типа
setArguments(String anyString);и аналогичный метод в адаптереvoid setArguments(String anyString, Int fragmentPos) { fragments.get(fragmentPos).setArguments(anyString); }и передавать туда что-либо динамически. Если ваши фрагменты будут различны, то вам придется еще обрабатывать логику для каждого фрагмента, но мне суть остается той же.
Еще вариант это сделать общую сущность которая будет шариться между
Activityи всеми фрагментамиViewPager-а- Singleton илиPresenter/ViewModelи шарить нужные данные через эту сущность. Для динамического управления фрагментами я бы использовал именно этот способ.
@Sergei Buvaka, спасибо за ответ. Сделал так:
В MainActivity:
pagerAdapter = new MainPagerAdapter(this);
pagerAdapter.setData(fragment1Container);
В MainPagerAdapter:
public class MainPagerAdapter extends FragmentStateAdapter
{
private Fragment1Container fragment1Container;
private Fragment2Container fragment2Container;
public void setData(Fragment1Container container)
{
fragment1Container = container;
}
public void setData(Fragment2Container container)
{
fragment2Container = container;
}
@NonNull
@Override
public Fragment createFragment(int position)
{
switch (position)
{
case 0:
Fragment1 fragment1 = new Fragment1();
Bundle bundle = new Bundle();
Gson gson = new Gson();
bundle.putString("fragment1Container", gson.toJson(fragment1Container));
fragment1.setArguments(bundle);
return fragment1;
case 1:...
В Fragment1:
private Fragment1Container fragment1Container;
if (bundle != null)
{
Gson gson = new Gson();
String jsonString = bundle.getString("fragment1Container");
Type entityType = new TypeToken<Fragment1Container>(){}.getType();
fragment1Container = gson.fromJson(jsonString , entityType );
}