1

I' m trying to improve my android app. I have main app menu (with possible actions) in a GridView 3x3. And I decided to add ViewPager to separate my grid. Before I've added ViewPager, I had only one Activity with GridView. In my onCreate method, I calculated the window height with DisplayMetrics to understand, what height should I use for my GridView items.
Now I'm trying to use ViewPager with Fragments. I have my Activity with ViewPager, and 2 Fragments. Each Fragment has the same layout (GridView in LinearLayout). I'm trying to pass screen height into Fragment in this way:

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);

}

So, each launch of onCreate method should recreate Fragments.

And in Fragment, I get my height in this way:

@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;
}

The problem is: when I rotate my device, all methods are called, but

height = this.getArguments().getInt("containerHeight");

uses old value. For instance, in first launch (vertical screen orientation), it is 690. When I rotate my device, in onCreate I calculate new height (382), but my Fragment takes old value (690).
I tried to call getArguments() in several places (onAttach, onCreate, onActivityCreated), but didn't help.
Can anybody explain me, where is the problem, and what should I do?
Thank you!

UPD: Code of my 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));
}
}
user3533397
  • 191
  • 1
  • 2
  • 14
  • Possible duplicate of [How to pass Arguments to Fragment from Activity](https://stackoverflow.com/questions/28829509/how-to-pass-arguments-to-fragment-from-activity) – Hossam Hassan Nov 21 '18 at 11:22
  • I'm not sure that it duplicates question you've pointed. Do you suggest me to use newInstance in my Fragment? I can pass data into Fragment using Bundle, but I don't understand, why it uses old value (passed in first Bundle). – user3533397 Nov 21 '18 at 11:29
  • post your code in onCreate – karan Nov 21 '18 at 11:30
  • use MVVM ViewModel pattern to solve this problem – Mitesh Vanaliya Nov 21 '18 at 13:35

2 Answers2

1

I'm not sure but i think it's because of supportFragmentManager and pagerAdapter.

First time in instantiateItem it creates a name for fragment and in destroyItem it's just detach fragment. Then after rotating in instantiateItem it founds fragment by name and uses old instance instead of new. I think for optimization and so on.

As a solution, you can remove all fragments from supportFragmentManager or override instantiateItem/destroyItem to remove frgament as you need.

Merov
  • 1,028
  • 1
  • 14
  • 29
0

I found another way to do this. In my Activity, I've created public method to calculate height, and in onCreateView in my Fragment, I call this method. It works.
But for me, it's unknown problem: why recreation of the fragment took values of arguments from the old bundle.

user3533397
  • 191
  • 1
  • 2
  • 14