I'm populating fragments in a tablayout. I have a method in one of my fragments, and i want to call it from an activity. But when i tried to have reference of the fragment by doing like this Fragment myFragment = (Fragment ) getSupportFragmentManager().findFragmentById(R.id.my_fragment), myFragment is null. I'm new to android. (Sorry for the bad english)
My code so far.
public class DashboardActivity extends AppCompatActivity {
private ViewPager pager;
private TabLayout tabLayout;
private Toolbar dashboardToolbar;
public static int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard_activity);
HomeFragment myFragment = new HomeFragment ();
if(getSupportFragmentManager().findFragmentById(R.id.homeFragment) == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.homeFragment, myFragment).commit();
}
pager = (ViewPager) findViewById(R.id.view_pager);
setupViewPager(pager);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager);
pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
// Toast.makeText(DashboardActivity.this, "tabSelected: " + tab.getText()+" "+ tab.getPosition(), Toast.LENGTH_SHORT).show();
// no where in the code it is defined what will happen when tab is tapped/selected by the user
// this is why the following line is necessary
// we need to manually set the correct fragment when a tab is selected/tapped
// and this is the problem in your code
pager.setCurrentItem(tab.getPosition());
position = tab.getPosition();
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
// Toast.makeText(DashboardActivity.this, "tabReSelected: " + tab.getText(), Toast.LENGTH_SHORT).show();
position = tab.getPosition();
// Reload your recyclerView here
}
});
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new HomeFragment(), "FOR YOU");
adapter.addFragment(new NotificationFragment(), "NOTIF");
adapter.addFragment(new ChatFragment(), "CHAT");
adapter.addFragment(new ProfileFragment(), "PROFILE");
viewPager.setAdapter(adapter);
}
}
Fragment
public class HomeFragment extends Fragment {
// Objects Declaration
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.homeFragment, container, false);
}
public void myMethod(){ //method to be called
//do something
}
}
Activity
public class MyActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_filter);
HomeFragment myFragment= (HomeFragment ) getSupportFragmentManager().findFragmentById(R.id.homeFragment);
if(myFragment!= null) {
Toast.makeText(ActivityFilter.this, "Not null.", Toast.LENGTH_SHORT).show();
home.myMethod(); // this line is not accessed since myFragment is null
}else{
Toast.makeText(ActivityFilter.this, "Null fragment.", Toast.LENGTH_SHORT).show();
}
}
}
You should use a Callback.
Create a public interface in your fragment.
public interface iCommunicateListener{
void communicate(String msg);
}
You also have to make the activity your listener.
(You can have many listeners, but fragments are supposed to be reusable, so if you have many listeners it will not be as reusable as it could and should be)
private iCommunicateListener listener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
listener = (iCommunicateListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement iCommunicateListener");
}
}
Now you have active listener.
In your onClicks or whenever you want send information to your activity, you have to call listener.communicate("doSomething");
Your Activity must implement the iCommunicateListener.
After implementation of the method communicate you can choose your logic for the different Strings or whatever you want to send through the callback.
There are many other ways for communication between Activities and Fragments, but since you are just beggining learn this one. After you implement it and you see the result you can take a look at this library which will definately help you in your android development. EventBus
With EventBus you will not have to use the callbacks which will make your fragments even more reusable and flexible, but first learn the normal Callbacks. It is a basic pattern and you will use it in many different situations.
More on Fragments: Fragments
Hope this helps!
Related
in my TabLayout i create my login TabItem dynamically at the onCreate() method of my MainActivity , but every time i exit from my application with back button and i re-enter my app , it creates that login TabItem again and so it doubles it every time , i tried to check and use :
if(savedInstanceState == null) {
// create the first tab
}
but it didn't work , can you please help me ?
here is my code for the MainActivity :
public class MainActivity extends AppCompatActivity {
TabLayout tabLayout;
ViewPager viewPager;
public static List<Fragment> fragments = new ArrayList<>();
public static List<String> fragmentsTitle = new ArrayList<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = findViewById(R.id.myTabLayout);
viewPager = findViewById(R.id.myViewPager);
MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
Adapter.createTab(new LoginFragment(), "Login", getSupportFragmentManager(), viewPager);
viewPager.setAdapter(Adapter);
tabLayout.setupWithViewPager(viewPager);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
public void onTabSelected(TabLayout.Tab tab) {
}
public void onTabUnselected(TabLayout.Tab tab) {
}
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
and this is the code for FragmentPagerAdapter
public class MyViewPagerAdapter extends FragmentPagerAdapter {
public MyViewPagerAdapter(FragmentManager manager) { super(manager);}
public void createTab(Fragment fragment, String title, FragmentManager manager, ViewPager viewPager) {
MyViewPagerAdapter Adapter = new MyViewPagerAdapter(manager);
MainActivity.fragments.add(fragment);
MainActivity.fragmentsTitle.add(title);
Adapter.notifyDataSetChanged();
viewPager.setAdapter(Adapter);
}
public Fragment getItem(int position) {
return MainActivity.fragments.get(position);
}
public CharSequence getPageTitle(int position) {
return MainActivity.fragmentsTitle.get(position);
}
public int getCount() {
return MainActivity.fragments.size();
}
}
Try removing static keyword from your list in MainActivity. Instead use final to prevent reinitialisation of list.
It's creating that tab everytime because static things stay alive as long as they get killed. And the professional way on earth to create tab and store them inside list is to keep that list inside viewpager adaptor.
I am happy it was helpful.
I have a ViewPager with 3 tabs.
I'm loading big data in every fragments.
The app load every fragments but I want to load fragment only when its selected.
How can I do that? I have no idea.
I'm waiting for your help. Thank you
my code:
public class Fragments extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FirstFragment(), "1");
adapter.addFragment(new SecondFragment(), "2");
adapter.addFragment(new ThirdFragment(), "3");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
If no one has given you a good answer I know this is 5 years later, but anyone reading this. I'm actually having the opposite problem. I need to load all tabs at the same time. What is happening to me now is only one tab is loading at a time. I need to use this adapter for viewpager2 with tablayout so that I can disable the viewpager swiping left to right for my specific usecase.
Here is my code:
WARNING CODE IS IN KOTLIN NOT JAVA
class RecipeTabAdapter internal constructor(fm: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fm, lifecycle) {
val fragmentsList: ArrayList<Fragment> = arrayListOf()
fun addFragment(fragment: Fragment) {
fragmentsList.add(fragment)
}
override fun getItemCount(): Int {
return fragmentsList.size
}
override fun createFragment(position: Int): Fragment {
when (position) {
position -> fragmentsList[position]
position -> fragmentsList[position]
}
return fragmentsList[position]
}
}
Is it possible to disable the offscreen page limit?
No. It is already set to the minimum possible value: one page to each side of the viewed page. This is necessary to have the animation effects work -- you see parts of two fragments (original and new) at the same time.
In
OncreateView(){
//.... dont initialize your view here
if(isMenuVisible()) { // menu should be visible if current fragment is visible right now
setUserVisibleHint(true); // manually set value to true
}
}
in
oncreate(){
setHasOptionsMenu(true);
}
Finally there is method called setuservisiblehint() which is only called when the fragment is visible to the user this is the only method where you shud initialize all your views.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && v != null) {
// initialize your view here and call you fetch_data_function()
}
Here's my solution and it works as expected. In all of your child fragments create a boolean variable:
private boolean loadFragmentExecuted = false;
in the child fragments create a generic method called loadFragment and move all of the logic you added in onCreateView to that method:
public void loadFragment()
{
if(!loadFragmentExecuted)
{
//Add your logic to manipulate the UI or load data etc...
loadFragmentExecuted = true;
}
}
in your pageview logic create the fragments dynamically like:
//add the fragment
String fragmentName = "com.something." + fragmentId;
//check if the class exists
try
{
Class myFragmentClass = Class.forName(fragmentName);
Fragment myFragment = (Fragment) myFragmentClass.newInstance();
mFragments.add(myFragment);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
then set your pager adapter and attach a tablayout with it:
//set our pager adapter that contains different fragments
mPagerAdapter = new BasePagerAdapter(mFragmentManager, mFragments);
//link the adapter to the viewpager
mViewPager.setAdapter(mPagerAdapter);
//cache fragments
int limit = (mPagerAdapter.getCount() > 0 ? mPagerAdapter.getCount() : 1);
mViewPager.setOffscreenPageLimit(limit);
//add the page listner to the viewPager and link it to the tabLayout
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
//on tab selected select current viewpager item
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
#Override
public void onTabSelected(TabLayout.Tab tab)
{
mViewPager.setCurrentItem(tab.getPosition());
//get fragment for the selected tab
Fragment f = mPagerAdapter.getItem(tab.getPosition());
//load the content of the fragment
try
{
Class c = f.getClass();
Method loadFragment = c.getMethod("loadFragment");
loadFragment.invoke(f);
}
catch (IllegalAccessException e){}
catch (InvocationTargetException e){}
catch (NoSuchMethodException e){}
}
#Override
public void onTabUnselected(TabLayout.Tab tab)
{
}
#Override
public void onTabReselected(TabLayout.Tab tab)
{
}
});
I have a solution that does not require subclassing, and it's easy to introduce into existing projects. It uses the child fragment mechanism.
The basic idea is to replace your content fragment with an almost empty fragment, and add your content fragment as a child fragment when it is really visible to the user
The gist of the code is like this
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
boolean hasFragment = getChildFragmentManager().findFragmentById(R.id.container) != null;
if (hasFragment) {
return;
}
if (getUserVisibleHint()) {
addFragment("onViewCreated");
}
}
#Override
public void onResume() {
super.onResume();
if (getUserVisibleHint()) {
addFragment("onResume");
}
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isResumed()) {
addFragment("setUserVisibleHint");
}
}
private void addFragment(String cause) {
if (getChildFragmentManager().findFragmentById(R.id.container) == null) {
getChildFragmentManager().beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.add(R.id.container, createFragment()).commit();
}
}
Check out my full solution here, which also contains a progressbar, and the option to automatically start loading of background fragments with a specified delay: Lazy Load Fragment
App open on first fragment and there is 2 tabs i want to refresh second fragment
when i move to it but i don't want to refresh first fragment
MainActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Main_Button(), "Main");
adapter.addFragment(new TwoFragment(), "Main2");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
please explain your answer because i'm new in android and i don't know how i can do that
When a Fragment is made visible (i.e., the selected page in your ViewPager), its setUserVisibleHint() method is called. You can override that method in your TwoFragment and use it to trigger a refresh.
public class TwoFragment extends Fragment {
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Refresh your fragment here
}
}
Inside Your fragment class use the below code:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
}
}
Try This
ViewPager mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
As of 2020 it is advisable to use architecture components(MVVM) such as LiveData and viewModel
This way all Fragments can share the same state
see docs here https://developer.android.com/jetpack/guide
Try this - it works for me
This code reloads current fragment, when it visible to user. Works when swiping and when back button pressed on next fragment.
#Override
public void setUserVisibleHint(boolean isVisible) {
super.setUserVisibleHint(isVisible);
if (isVisible) {
FragmentTransaction ftr = getFragmentManager().beginTransaction();
ftr.detach(this).attach(this).commit();
}
}
If you wouldn't mind refreshing every fragment every time a tab changes, you could simply override the getItemPosition() method of your FragmentPagerAdapter and make it return always the value POSITION_NONE. Example:
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
By doing that, you tell android to refresh the fragment each time the view pager tries to get it. Performance wise, it isn't the best practice. So there is a second approach:
First, create an interface to be called when your need refresh:
public interface Updatable {
public void update();
}
Then, make your fragments implement this interface:
public class MyFragment extends Fragment implements Updateable {
...
#Override
public void update() {
// refresh your fragment, if needed
}
}
If your really wish to not update your first fragment, do nothing in its update() method.
Third, override the getItemPosition method and call update(). This will be called every time a fragment gets selected:
#Override
public int getItemPosition(Object object) {
Updatable f = (Updatable) object;
if (f != null) {
f.update();
}
return super.getItemPosition(object);
}
Most of this code came from this answer.
you could use ViewPager.addOnPageChangeListener to listen to when the fragments are swiped and incorporate some type of action there.
Hey StackOverFlow community ! I really need help.. :(
I'm searching for 2 or 3 hours now and didn't find anything that is relevant and simple.
I explain the context :
I have an Activity A1. This activity contains 3 fragments F1, F2, F3. It uses a ViewPager so the 3 fragments are in facts selected either by selecting a tab or by swiping the screen and this works.
What I want to do now :
For some reasons, I call a Web Service for data in the activity. The data is dependent on the intent that the activity A1 gets from the original calling activity A0 (It's a group_id). So, I want to send this data that I get in A1 from the Web Service to each of my fragments F1, F2 and F3.
Do you have a solution or an explanation of how the to pass data to fragments in ViewPager ?
Thanks a lot!
There is the base code of my Activity A1 :
public class ShowGroupActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Infos", "Parcours", "Mur" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_show_group);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
Here is an example of a fragment : F1 (In which I want to display some data given by A1).
public class GroupInfoFragment extends Fragment {
public GroupInfoFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_group_info, container, false);
return v;
}
}
The easiest and fastest way to do it is by using EventBus.
Just post an event at your onResponse method in the activity and the fragment will handle the rest.
Activity-
Create a NetworkResponceEvent class
OnResponse called: post a new NetworkResponceEvent to the eventbus.
Fragment-
Register- onResume
UnRegister- osPause
Create method onEvent(NetworkResponceEvent e)- handle all of the
updates here.
You should use the getActivity() method from your fragments.
I would recommend declaring an interface inside your fragment, like this:
public class GroupInfoFragment extends Fragment {
...
public interface Callbacks {
// you should declare methods for returning the data you want form your activity here
Foo getData();
}
...
}
And then implementing this interface in your ShowGroupActivity class, like this:
public class ShowGroupActivity extends FragmentActivity implements
ActionBar.TabListener, GroupInfoFragment.Callbacks {
...
#Override
Foo getData() {
return mData;
}
...
}
Then you would be able to get the data you want from your fragment classes by calling:
GroupInfoFragment.Callbacks callbacks = (GroupInfoFragment.Callbacks) getActivity();
Foo data = callbacks.getData;
By doing this, you can implement your fragment class without worrying about the activity implementation.
Additional Notes
You can also override your fragment's onAttach() method so you can always guarantee that your fragment is being attached to an activity that implements the Callback interface. You can also keep a reference to the Callback instance:
Callbacks mCallbacks;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new ClassCastException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
I am having trouble with an Activity that fires off a command to a fragment in a ViewPager using a FragmentNotification interface. Everything works well until either the app is in the background for a long period of time or the orientation changes. At that point the Activity seems to lose connection to the Fragment.
My Activity code:
public class MyActivity extends FragmentActivity implements MyFragment3.FragmentNotification {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
MyFragment1 fragOne = new MyFragment1();
MyFragment2 fragTwo = new MyFragment2();
MyFragment3 fragThree = new MyFragment3();
boolean toggle = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setClickable(true);
mViewPager.setCurrentItem(0);
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
if (fragThree != null) {
fragThree.doSomething();
toggle = false;
return false;
} else {
}
}
return super.onKeyDown(keyCode, event);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment;
if(i==0){
fragment = fragOne;
}else if(i==1){
fragment = fragTwo;
}else{
fragment = fragThree;
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return getString(R.string.title_section1).toUpperCase();
case 1: return getString(R.string.title_section2).toUpperCase();
case 2: return getString(R.string.title_section3).toUpperCase();
}
return null;
}
}
//Receive an event notification from a fragment
// #Override
public void fragmentAction(int actionType) {
if (actionType == MyFragment3.TOGGLE_ACT) {
toggle = true;
}
}
}
My Fragment Code:
public class MyFragment3 extends Fragment {
View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
mView = ....
return rootView;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (FragmentNotification) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
public void doSomething(){
mView.setVisibility(View.GONE);
...
}
public interface FragmentNotification {
public void fragmentAction(int actionType);
}
}
As mentioned, everything works well until some state change, and then it appears the activity loses reference to the fragment present in the viewpager, even though it is being displayed properly until the back button is pressed.
I believe I need to restore the connection by supplying a bundle from my Fragment's onSaveInstanceState, but have no idea how to get started.
Any help would be greatly appreciated.
Thanks,
Josh
You are blindly creating instances of your three fragments, in data member initializers (!), even if those fragments already exist. Bear in mind that Android recreates all of your existing fragments on a configuration change. Hence, on a configuration change, none of those newly-created fragments will get used, as the ViewPager will use the ones Android recreated for it. You can see this in the implementation of instantiateItem() in FragmentPagerAdapter (source code is in your SDK).
The concept that "when pressing BACK I want to do something special with my third fragment in the pager" is not something that ViewPager supports all that well. I would encourage you to find some other solution to whatever problem you are trying to solve with that logic.