Send network request as FragmentPagerAdapter shows the Fragment - android

I am using the FragmentPagerAdapter which shows three fragments by using ViewPager. I have setOffscreenPageLimit to 3 so all the three fragments send the network request simultaneously as they are visible(I have send the network request on Fragment.onActivityCreated()). But I want network request is send only when Fragment is visible(means user is scrolled to that fragment).
Note: I am using the setOffscreenPageLimit to 3 because every time the fragment is created no new network request is created and show the catches fragment

Making network requests in oncreateview () of every fragment should do what you want to.
example :Something that ive been using .
Parent activity with fragment pager adapter.
public class HomeActivity extends SherlockFragmentActivity{
private static final String[] CONTENT = new String[] { "Fragment 1", "Fragment 2" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homexml);
Bundle extra = getIntent().getExtras();
int i = Integer.parseInt(extra.getString("id"));
FragmentPagerAdapter adapter = new FragmentAdapter(getSupportFragmentManager());
ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.indicator);
indicator.setViewPager(pager);
switch (i)
{
case 2:
pager.setCurrentItem(0);
break;
case 3:
pager.setCurrentItem(1);
// break;
// case 4:
// pager.setCurrentItem(3);
// break;
// case 5:
// pager.setCurrentItem(4);
// break;
// case 6:
// pager.setCurrentItem(5);
// break;
// case 7:
// pager.setCurrentItem(6);
// break;
// default:
// pager.setCurrentItem(0);
// break;
}
indicator.setFooterIndicatorStyle(IndicatorStyle.Underline);
indicator.setFooterColor(Color.parseColor("#e7c450"));
}
class FragmentAdapter extends FragmentPagerAdapter {
SherlockFragment frg;
public FragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public SherlockFragment getItem(int position) {
switch (position)
{
case 0:
frg = new fragment1();
break;
case 1:
frg = new fragment2();
break;
}
return frg;
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position];
}
// #Override public int getIconResId(int index) {
// return ICONS[index];
// }
#Override
public int getCount() {
return CONTENT.length;
}
}
Pass specify the fragments in the adapter. make network requests in onCreateView() of every fragment. that way network requests will be only made when fragment is visible.

Related

Change fragment on click

I have to implement an application in which the user can click through a bottom_bar between 5 pages (although google does not recommend it in recent documents, the customer is always right).
So I created a swipe activity with automatic tool android study.
Question: how do I start the transation, after the click on the button, and change fragment??
Here is the code (at the time the activity change with the swipe)
public class Home extends ActionBarActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
ImageView home, ospitalita,multimedia,territoro, prodotti;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
home = (ImageView) findViewById(R.id.ibHome);
ospitalita = (ImageView) findViewById(R.id.ibOspitalita);
multimedia = (ImageView) findViewById(R.id.ibMultimedia);
territoro = (ImageView) findViewById(R.id.ibTerritorio);
prodotti = (ImageView) findViewById(R.id.ibProdotti);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
View.OnClickListener gestore = new View.OnClickListener() {
#Override
public void onClick(View v) {
//this is the bottom bar, on click, change icon color
switch (v.getId()){
case R.id.ibHome:
changeBottomIcon("home");
mSectionsPagerAdapter.getItem(0); //do nothing
break;
case R.id.ibOspitalita:
changeBottomIcon("ospitalita");
mSectionsPagerAdapter.getItem(1);
break;
case R.id.ibMultimedia:
changeBottomIcon("multimedia");
mSectionsPagerAdapter.getItem(2);
break;
case R.id.ibTerritorio:
changeBottomIcon("territorio");
mSectionsPagerAdapter.getItem(3);
break;
case R.id.ibProdotti:
changeBottomIcon("prodotti");
mSectionsPagerAdapter.getItem(4);
break;
}
}
};
home.setOnClickListener(gestore);
ospitalita.setOnClickListener(gestore);
multimedia.setOnClickListener(gestore);
territoro.setOnClickListener(gestore);
prodotti.setOnClickListener(gestore);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
// change bottom doesn't work here
case 0:
// changeBottomIcon("home");
return new fragment_home();
case 1:
//changeBottomIcon("territorio");
return new fragment_territorio();
case 2:
//changeBottomIcon("ospitalita");
return new fragment_ospitalita();
case 3:
//changeBottomIcon("multimedia");
return new fragment_multimedia();
case 4:
//changeBottomIcon("prodotti");
return new fragment_prodotti();
}
return null;
}
#Override
public int getCount() {
//num pagine
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
//Not visible, no nav bar
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.home);
case 1:
return getString(R.string.territorio);
case 2:
return getString(R.string.ospitalita);
case 3:
return getString(R.string.multimedia);
case 4:
return getString(R.string.prodotti);
}
return null;
}
}
//simple method to change icon color
public void changeBottomIcon(String tipo){
.
.
.
//lo ometto perchè inutile
}
}
You can achieve this by calling:
mViewPager.setCurrentItem(index);
(see the android dev docs for further information)

Why my async task is too slow when it uses in pager adapter

I am using the following code
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
SectionsPagerAdapter mSectionsPagerAdapter= new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
My SectionsPagerAdapter class is
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
int numpages = 0;
numpages=5;
return numpages;
}
#Override
public CharSequence getPageTitle(int position) {
// Locale l = Locale.getDefault();
String chnl_name = "";
switch (language) {
case 1:
chnl_name = Constants.telugu_channels[position];
break;
case 2:
chnl_name = Constants.tamil_channels[position];
break;
case 3:
chnl_name = Constants.english_channels[position];
break;
case 4:
chnl_name = Constants.hindi_channels[position];
break;
}
return chnl_name;
}
}
and fragment class is
// enter code here
public static class DummySectionFragment extends Fragment {
GridView gridplaylst;
ProgressBar progress;
Play_list playlist;
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_grid, container,
false);
// dummyTextView.setText(Integer.toString(getArguments().getInt(
// ARG_SECTION_NUMBER)));
gridplaylst = (GridView) rootView.findViewById(R.id.gridplaylst);
progress = (ProgressBar) rootView.findViewById(R.id.progress);
if (playlist != null)
playlist.cancel(true);
if (language != 0) {
int a = getArguments().getInt(ARG_SECTION_NUMBER);
switch (language) {
case 1:
playlist = new Play_list(
Constants.telugu_playlists[getArguments().getInt(
ARG_SECTION_NUMBER) - 1]);
playlist.execute();
break;
case 2:
new Play_list(Constants.tamil_playlists[getArguments()
.getInt(ARG_SECTION_NUMBER) - 1]).execute();
break;
case 3:
new Play_list(Constants.english_playlists[getArguments()
.getInt(ARG_SECTION_NUMBER) - 1]).execute();
break;
case 4:
new Play_list(Constants.hindi_playlists[getArguments()
.getInt(ARG_SECTION_NUMBER) - 1]).execute();
break;
}
}
}
and playlist is a async task like
public class Play_list extends AsyncTask<Object, Object, Object> {
protected Object doInBackground(Object... arg0) {
}
}
Here all the functionality is working fine, but my problem is the data downloading by the async tasks is too slow.
I think the problem is creating a new task every time.
Please suggest me how can i overcome this problem.
#Prakash : There is a catch while you use ViewPager. ViewPager will start preparing view for next 2 fragments and as when your activity with ViewPager is called by System , ViewPager will creating next 2 views that you have defined in FragmentPagerAdapter.
You can use setOffscreenPageLimit(pagestoCache) to minimize this functionality.
Prakash , now you have to call asyn task only when fragment is visible to user and cancel if user moves out of current fragment. Why i am asking because if you are not cancelling the Aync task there will be many thread will be running in application space. You can also chaeck if you can use ThreadPoolExecutor in your code.
Are you aware of the fact, that Android does not run AsyncTasks in parallel? If you start many AsyncTasks in a row, they are queued and executed one after the other?
You can overcome this, by starting them with executeOnExecutor(...) instead of regular execute().

How to handle AsyncTask's in ActionBarActivity Fragments when ViewPager is used?

I'm using ActionBarActivity to create 5 tabs. I have used ViewPager to swipe between the 5 tabs using SectionsPagerAdapter which extends FragmentPagerAdapter. Each tab has a fragment with an asynctask called in oncreateview method. When I'm in one fragment, asynctask in other fragment is being called.
I tried using toast messages in oncreateview method is each fragment instead of asynctask. But wrong toast messages are being fired in wrong fragment.
Oncreate method code:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager_exp);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
actionBar.setTitle(getHomePageTitle(position));
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++)
{
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setIcon(getPagedrawable(i))
.setTabListener(this));
}
// Adapter class code:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
Fragment1 f1 = new Fragment1();
return f1;
case 1:
Fragment2 f2 = new Fragment2();
return f2;
case 2:
Fragment3 f3 = new Fragment3();
return f3;
case 3:
Fragment4 f4 = new Fragment4();
return f4;
case 4:
Fragment5 f5 = new Fragment5();
return f5;
}
return null;
}
#Override
public int getCount() {
// Show 5 total pages.
return 5;
}
}
Fragemnt class code :
public class F1 extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#SuppressLint("NewApi")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.f1,container, false);
Toast.makeText(getActivity(), "F1", Toast.LENGTH_SHORT).show();
return view;
}
}
The FragmentPagerAdapter keeps additional fragments, besides the one shown, in resumed state. The solution is to implement a custom OnPageChangeListener and create a new method for when the fragment is shown.
1) Create LifecycleManager Interface
The interface will have two methods and each ViewPager’s Fragment will implement it. These methods Are as follows:
public interface FragmentLifecycle {
public void onPauseFragment();
public void onResumeFragment();
}
2) Let each Fragment implement the interface
Add iplements statement for each class declaration:
public class FragmentBlue extends Fragment implements FragmentLifecycle
public class FragmentGreen extends Fragment implements FragmentLifecycle
public class FragmentPink extends Fragment implements FragmentLifecycle
3) Implement interface methods in each fragment
In order to check that it really works as expected, I will just log the method call and show Toast:
#Override
public void onPauseFragment() {
Log.i(TAG, "onPauseFragment()");
Toast.makeText(getActivity(), "onPauseFragment():" + TAG, Toast.LENGTH_SHORT).show();
}
#Override
public void onResumeFragment() {
Log.i(TAG, "onResumeFragment()");
Toast.makeText(getActivity(), "onResumeFragment():" + TAG, Toast.LENGTH_SHORT).show();
}
4) Call interface methods on ViewPager page change
You can set OnPageChangeListener on ViewPager and get callback each time when ViewPager shows another page:
pager.setOnPageChangeListener(pageChangeListener);
5) Implement OnPageChangeListener to call your custom Lifecycle methods
Listener knows the new position and can call the interface method on new Fragment with the help of PagerAdapter. I can here call onResumeFragment() for new fragment and onPauseFragment() on the current one.
I need to store also the current fragment’s position (initially the current position is equal to 0), since I don’t know whether the user scrolled from left to right or from right to left. See what I mean in code:
private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
int currentPosition = 0;
#Override
public void onPageSelected(int newPosition) {
FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
fragmentToShow.onResumeFragment();
FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
fragmentToHide.onPauseFragment();
currentPosition = newPosition;
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
public void onPageScrollStateChanged(int arg0) { }
};
I didn't write the code. Full tutorial here: http://looksok.wordpress.com/2013/11/02/viewpager-with-detailed-fragment-lifecycle-onresumefragment-including-source-code/
Use this
viewPager.setOffscreenPageLimit(1); // the number of pages you want to load in background
and also a ProgressDialogue.
ViewPager creates views for fragments adjacent to your current page. This also gives you an opportunity to load any data required for the adjacent fragments. If you are using AsyncTasks to load data, using this feature will result in a better user experience. But if you need an event when a particular page is opened by the viewpager, LordRaydenMK's solution will work.
See my post on the following thread for using AsyncTasks in a ViewPager:
AsyncTask runs on each page of the ViewPager
Hi You can try by using tag of each fragment and call method of each fragment on Page Changed
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
actionBar.setTitle(getHomePageTitle(position));
Fragment f = getFragrmentManager().findFragmentByTag(
"" + position);
if (f != null)
f.refresh();
}
});
and on
#Override
public Fragment getItem(int position) {
Fragment f=null;
switch (position)
{
case 0:
f = new Fragment1();
break;
case 1:
f = new Fragment2();
break;
case 2:
f = new Fragment3();
break;
case 3:
f = new Fragment4();
break;
case 4:
f = new Fragment5();
break;
}
f.setTag(""+position);
return f;
}

Strange onPause(), onResume() behaviour in fragments

The application has a main activity (MainActivity.java) with three tabs (fragments). I can navigate between them using the swipe left (riht) or clicking on a specific tab.
Upon starting the application, the 1st fragment is shown.
If I go to the 2nd fragment from the 1st fragment and then back to the 1st fragment, nothing happens (onResume() of the 1rd fragment isn't called), so it doesn't refresh it's content.
If I go to the 3rd fragment from the 1st fragment and then directly back to the 1st fragment, the onCreateView() of fragment1 is created and it's onResume() is called, which is correct.
If I go from the 3rd fragment to the 2nd fragment, the onCreateView() and onResume() of fragment1 are called, but not the onCreateView of fragment2.
I guess the logic in MainActivity isn't right, so I would kindly ask someone to take a look and tell me what could be wrong.
MainActivity.java:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
CollectionPagerAdapter mCollectionPagerAdapter;
public TTSocket socket;
DBHandler db;
public String logged_user;
private LogedinPerson person;
ViewPager mViewPager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();
logged_user = extras.getString("logged_user");
socket = TTSocket.getInstance();
socket.currentRef = this;
db = new DBHandler(this);
person=db.getLogedInPerson();
socket.dbHandler=db;
socket.person=person;
if(!socket.isInit){
String typeInitStr = "{\"Type\":\"Init\", \"UserId\":\""+ person.getUserId() +"\"}";
socket.Send(typeInitStr);
}
mCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
// Set up action bar.
final ActionBar actionBar = getActionBar();
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener
// for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Log.d("TEST",position+"");
// the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if
// we have a reference to the Tab
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter.
// Also specify this Activity object, which implements the
// TabListener interface, as the
// listener for when this tab is selected.
if(i == 0){
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.messages)
.setTabListener(this));
}else if(i == 1){
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.contacts)
.setTabListener(this));
}else{
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.history)
.setTabListener(this));
}
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
socket.currentRef = this;
socket.dbHandler=db;
socket.person=person;
//mCollectionPagerAdapter.notifyDataSetChanged();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the primary sections of the app.
*/
public class CollectionPagerAdapter extends FragmentPagerAdapter {
final int NUM_ITEMS = 3; // number of tabs
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
/*
#Override
public Fragment getItem(int i) {
Fragment fragment = new TabFragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, i);
fragment.setArguments(args);
return fragment;
}
*/
#Override
public Fragment getItem(int position) {
Fragment fragment = new Fragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, position);
switch (position) {
case 0:
Log.i("Fragment", "0");
fragment = new Tab1Fragment();
fragment.setArguments(args);
return fragment;
case 1:
Log.i("Fragment", "1");
fragment = new Tab2Fragment();
fragment.setArguments(args);
return fragment;
case 2:
Log.i("Fragment", "2");
fragment = new Tab3Fragment();
fragment.setArguments(args);
return fragment;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
String tabLabel = null;
switch (position) {
case 0:
tabLabel = getString(R.string.label1);
break;
case 1:
tabLabel = getString(R.string.label2);
break;
case 2:
tabLabel = getString(R.string.label3);
break;
}
return tabLabel;
}
}
/**
* A fragment that launches other parts of the demo application.
*/
public static class TabFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle args = getArguments();
int position = args.getInt(ARG_OBJECT);
int tabLayout = 0;
switch (position) {
case 0:
tabLayout = R.layout.tab1;
break;
case 1:
tabLayout = R.layout.tab2;
break;
case 2:
tabLayout = R.layout.tab3;
break;
}
View rootView = inflater.inflate(tabLayout, container, false);
return rootView;
}
}
}
Strange onPause(), onResume() behaviour() in fragments
It's not strange behaviour but native behaviour of ActionSherlock. This kind of behaviour is used for caching -> optimalisation for older devices with lower RAM this is reason why fragments are cached.
If you need to update content of fragment don't try to replace its layout or something similar. If you want to update fragment when scrolling between pages, you need to use method of FragmentPagerAdapter:
#Override
public int getItemPosition(Object object) {
// implementation
return super.getItemPosition(object);
}
This method is called when you will call
notifyDataSetChanged();
on your FragmentPagerAdapter. It's handy method for make updates of your fragments. There are more ways how to do it but here i'll show you how I'm doing it.
Let your fragments implement interface for example called Updateable:
interface Updateable {
public void update();
}
public class MyFragment extends SherlockFragment implements Updateable {
#Override
public void update() {
// perform Fragment updates
}
}
And in this method you will perform updates. Now back to getItemPosition() method. This method will be used for invoking update() method from Fragment i.e:
#Override
public int getItemPosition(Object object) {
Fragment f = (Fragment) object;
// determine which fragment
if (f instanceof MyFragment) {
((MyFragment) f).update(); // invokes update() method
}
return super.getItemPosition(object);
}
Now whenever you scroll page or tap on some tab (you need also call notifyDataSetChanged()) you are able to make Fragment updates. This way is more efficient against destroying and recreating fragment(s) each time you scrolling or clicking on tabs. But how i said this is not only solution there are more possible solutions.
Note: getItemPosition() can return two values: POSITION_NONE and UNCHANGED. Difference between both is that first indicates that Fragment will be always destroyed and recreated that is not very efficient and second indicates that Fragment won't be changed (is in on right place).
For more detailed explanation look here.
That is because ViewPager doesn't hide all fragments you switch.
You can control this behaviour by setOffscreenPageLimit

NullPointerException with ViewPager after the app has been killed

I have 3 pages in a ViewPager: instances of Tab0, Tab1, Tab2. In the main Activity, I'm storing the instance of each tab in separte variables from the SectionsPagerAdapter's getItem() function.
I assume that ViewPager always initializes the current tab, the tab to the left of it, and the tab to the right of it.
These are my instances: Tab0 t0; Tab1 t1; Tab2 t2;
The app works fine initially. But if i press the home button (to trigger onPause()), kill the app from task killer (or assume that android itself has killed it), and open the app again, i get NullPointerExceptions in onPageSelected because t0, t1 and t2 are now null.
This is my onCreate method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int pos) {
switch(pos){
case 1:
t1.lookup()
break;
case 0:
t0.doSomething();
break;
case 2:
t2.someThingElse();
break;
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
mViewPager.setCurrentItem(1,true);
}
This is my FragmentPagerAdapter (which is a nested class inside my Activity):
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment;
switch(position){
case 0:
fragment = t0 = new Tab0();
break;
case 1:
fragment = t1 = new Tab1();
break;
case 2:
fragment = t2 = new Tab2();
break;
default:
fragment=null;
}
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, position + 1);
if(fragment!=null)
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 1:
return getString(R.string.T1).toUpperCase(l);
case 0:
return getString(R.string.T0).toUpperCase(l);
case 2:
return getString(R.string.T2).toUpperCase(l);
}
return null;
}
}
From the Docs:
The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. Meaning when it comes back the fragments will be recreated for you but will not be the original ones(hence your loss of t* variables). I'd take a look at overriding saveState and restoreState methods to see if you can add the logic for setting up what the t* variables. If not perhaps in one of the other on* methods in the fragment.

Categories

Resources