Я пытаюсь улучшить свое приложение для Android. У меня есть главное меню приложения (с возможными действиями) в GridView 3x3. И я решил добавить ViewPager для разделения моей сетки. До того, как я добавил ViewPager, у меня была только одна активность с GridView. В моем методе onCreate я рассчитал высоту окна с помощью DisplayMetrics, чтобы понять, какую высоту я должен использовать для своих элементов GridView.
Сейчас я пытаюсь использовать ViewPager с фрагментами. У меня есть активность с ViewPager и 2 фрагмента. Каждый фрагмент имеет одинаковое расположение (GridView в LinearLayout). Я пытаюсь передать высоту экрана во фрагмент следующим образом:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_grid_layout);
pageHeight = getHeight();
Log.d("HEIGHT", "Page height: "+pageHeight);
ViewPager viewPager;
viewPager = findViewById(R.id.main_menu_viewpager);
src = new ArrayList<MainPageTableFragment>();
/*Определяем количество страниц меню*/
int pagesCount = 2;
for (int i = 0; i < pagesCount; i++) {
src.add(MainPageTableFragment.newInstance(i, pageHeight));
}
FragmentPagerAdapter adapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), src);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(viewPager, true);
}
Таким образом, каждый запуск метода onCreate должен воссоздавать фрагменты.
И во фрагменте я получаю свой рост таким образом:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
//PROBLEM IS HERE...
height = this.getArguments().getInt("containerHeight");
pageNum = this.getArguments().getInt("pageNumber");
populateGridItems(); //method to load items in gridview
return rootView;
}
Проблема в том, что когда я поворачиваю свое устройство, все методы вызываются, но
height = this.getArguments().getInt("containerHeight");
использует старое значение. Например, при первом запуске (вертикальная ориентация экрана) это 690. Когда я поворачиваю свое устройство, в onCreate я вычисляю новую высоту (382), но мой фрагмент принимает старое значение (690).
Я пытался вызвать getArguments() в нескольких местах (onAttach, onCreate, onActivityCreated), но не помогло.
Кто-нибудь может мне объяснить, где проблема и что мне делать?
Спасибо!
UPD: код моего MainPageTableFragment
public static MainPageTableFragment newInstance(int pageNumber, int height) {
Bundle args = new Bundle();
args.putInt("pageNumber", pageNumber);
args.putInt("containerHeight", height);
MainPageTableFragment fragment = new MainPageTableFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
height = getArguments().getInt("containerHeight");
Log.d("HEIGHT", "Fragment height in onCreateView: "+height);
pageNum = getArguments().getInt("pageNumber");
populateGridItems();
return rootView;
}
private void populateGridItems() {
/*adding items in GridView*/
gridView.setAdapter(new MenuGridAdapter(this.getContext(), items, height));
}
}
Я не уверен, но я думаю, что это из-за supportFragmentManager
и pagerAdapter
.
В первый раз в instantiateItem
он создает имя для фрагмента, а в destroyItem
он просто отсоединяет фрагмент. Затем, после вращения в instantiateItem
он находит фрагмент по имени и использует старый экземпляр вместо нового. Я думаю для оптимизации и так далее.
В качестве решения вы можете удалить все фрагменты из supportFragmentManager
или переопределить instantiateItem/destroyItem
для удаления фрагмента по мере необходимости.
Я нашел другой способ сделать это. В своей деятельности я создал открытый метод для вычисления высоты, и в onCreateView в моем фрагменте я вызываю этот метод. Оно работает.
Но для меня это неизвестная проблема: почему воссоздание фрагмента взяло значения аргументов из старого комплекта.