Passing arguments in Fragment
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));
}
}
add a comment |
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));
}
}
Possible duplicate of 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 Mer
Nov 21 '18 at 11:30
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35
add a comment |
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));
}
}
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));
}
}
edited Nov 21 '18 at 11:40
asked Nov 21 '18 at 11:16
user3533397
2429
2429
Possible duplicate of 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 Mer
Nov 21 '18 at 11:30
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35
add a comment |
Possible duplicate of 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 Mer
Nov 21 '18 at 11:30
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35
Possible duplicate of How to pass Arguments to Fragment from Activity
– Hossam Hassan
Nov 21 '18 at 11:22
Possible duplicate of 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
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 Mer
Nov 21 '18 at 11:30
post your code in onCreate
– Karan Mer
Nov 21 '18 at 11:30
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410948%2fpassing-arguments-in-fragment%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 21 '18 at 14:01
Merov
226315
226315
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 21 '18 at 13:16
user3533397
2429
2429
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410948%2fpassing-arguments-in-fragment%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Possible duplicate of 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 Mer
Nov 21 '18 at 11:30
use MVVM ViewModel pattern to solve this problem
– Mitesh Vanaliya
Nov 21 '18 at 13:35