Using backstack and back button in viewpager - android

I'm using a viewpager to swipe between fragments and would like the back button to navigate to the previously viewed fragment rather than ending the activity. Sorry if this is a duplicate of this question however I didn't find the answer very helpful. Obviously onBackPressed needs to be overridden, but I don't know how to get and display the correct fragment. I assume that I should use the fragmentmanager's backstack, but getSupportFragmentManager().getBackStackEntryCount() always returns 0. Do I need to manually add fragments to the backstack using FragmentTransaction.addToBackStack()? If so, where would I add this in my adapter?
Here is the code for my activity,
public class PagerActivity extends FragmentActivity {
ArrayList<Sale> sales;
MyAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent it = getIntent();
this.sales = (ArrayList<Sale>) it.getExtras().get("sales");
int position = it.getExtras().getInt("position");
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.fragment_pager);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(position);
}
public class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public int getCount() {
return sales.size();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
#Override
public Fragment getItem(int position) {
SalesThumbFragment frag = new SalesThumbFragment();
return frag.newInstance(sales.get(position));
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sales_controller, menu);
return true;
}
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() != 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}

In new design support library, i use this
I have same issue and i follow this step
In the main activity where there are 3 fragment in viewpager i create stack
and push and pop data.
//private Stack<Integer> stackkk; ==> As i get edit suggestion
private Stack<Integer> stackkk = new Stack<>(); // Edited
private ViewPager mPager;
private int tabPosition = 0;
mTabLayout.setupWithViewPager(mPager);
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tabPosition = tab.getPosition();
mPager.setCurrentItem(tab.getPosition());
if (stackkk.empty())
stackkk.push(0);
if (stackkk.contains(tabPosition)) {
stackkk.remove(stackkk.indexOf(tabPosition));
stackkk.push(tabPosition);
} else {
stackkk.push(tabPosition);
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tabPositionUnselected = tab.getPosition();
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
and in the onBackPressed in activity,
#Override
public void onBackPressed() {
if (stackkk.size() > 1) {
stackkk.pop();
mPager.setCurrentItem(stackkk.lastElement());
} else {
}
}

Use this code in Fragment Activity class. Don't forget to add return true;
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
mViewPager.setCurrentItem(viewPageSelected - 1);
return true;
}
return super.onKeyDown(keyCode, event);
}

I had a similar problem, this is how I solved it. I think you can adapt the code to your problem, if I understood what you problem is. I had a ViewPager with 6 fragments and wanted to keep track of the page history and to be able to use the back button to navigate backwards in the history. I create a java.util.Stack<Integer> object, add fragment numbers to it (except when you use the back button, see below), and override onBackPressed() to make it pop the last viewed fragment instead of using the back stack, when my history stack is not empty.
You want to avoid pushing elements on the Stack when you press the back button, otherwise you will get stuck between two fragments if you keep using the back button, instead of eventually exiting.
My code:
MyAdapter mAdapter;
ViewPager mPager;
Stack<Integer> pageHistory;
int currentPage;
boolean saveToHistory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.container);
mPager.setAdapter(mAdapter);
mPager.setOffscreenPageLimit(5);
pageHistory = new Stack<Integer>();
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
if(saveToHistory)
pageHistory.push(Integer.valueOf(currentPage));
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
saveToHistory = true;
}
#Override
public void onBackPressed() {
if(pageHistory.empty())
super.onBackPressed();
else {
saveToHistory = false;
mPager.setCurrentItem(pageHistory.pop().intValue());
saveToHistory = true;
}
};

If you use a field to keep track of the index of the previous page using mPager.getCurrentItem() after each time the user navigates to a new fragment, then in the onBackPressed() method, you should be able to call mPager.setCurrentItem(previousPage)
Or, if the user can only page in order, then you don't need a field at all, and you could just do mPager.setCurrentItem(mPager.getCurrentItem()-1)

I've made custom ViewPager and implement stack functionality in it.
public class CustomViewPager extends ViewPager {
private Stack<Integer> stack = new Stack<>();
#Override
public void setCurrentItem(int item, boolean smoothScroll) {
stack.push(getCurrentItem());
super.setCurrentItem(item, smoothScroll);
}
public int popFromBackStack(boolean smoothScroll) {
if (stack.size()>0) {
super.setCurrentItem(stack.pop(), smoothScroll);
return getCurrentItem();
} else return -1;
}

Related

When back button is pressed the APP exit. Why?

In my App when i press back button from the following activity doesn't return to main activity(fragment) but the App close.
public class ListaSmartphone extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lista_smartphone);
Button buttonSP = (Button)findViewById(R.id.buttonXIAOMI);
buttonSP.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent openListaSP = new Intent(ListaSmartphone.this, ElencoXiaomi.class);
startActivity(openListaSP);
}
});
Button buttonTB = (Button)findViewById(R.id.buttonMEIZU);
buttonTB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent openListaTB = new Intent(ListaSmartphone.this, ElencoMeizu.class);
startActivity(openListaTB);
}
});
}
}
THIS IS THE MAIN ACTIVITY CODE
public class MainActivity extends AppCompatActivity {
FragmentPagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
vpPager.setPageTransformer(true, new RotateUpTransformer());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 4;
private static final String[] TAB_TITLES = new String[]{"WOW STORE", "PRODOTTI", "SERVIZI", "INFO"};
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentWithZeroImage.newInstance("", R.drawable.wowstorelogo);
case 1:
return FragmentWithOneImage.newInstance("", R.drawable.prodotti);
case 2:
return FragmentWithTwoImages.newInstance("", R.drawable.riparazioni);
case 3:
return FragmentWithThreeImages.newInstance("", R.drawable.info);
default:
return null;
}
}
#Override
public int getCount(){
return TAB_TITLES.length;
}
#Override
public CharSequence getPageTitle(int position){
return TAB_TITLES[position];
}
}
}
The Application works fine, no error but on a devices whe back button is pressed the App exits and doesn't back to MainActivity.
I use Main Activity with four fragments.
While Passing Intent you might have used finish(); after startActivity()
use this code :
#Override
public void onBackPressed() {
this.startActivity(new Intent(ListaSmartphone.this,MainActivity.class));
// super.onBackPressed();
}
and open the fragment in onCreate function of MainActivity
If you want to go back to the MainActivity on back button press then use this code
#Override
public void onBackPressed() {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
}

How to add back button on action bar with more tabs

know anyone how can I add one back button on my action bar? I want to add the back button befor INFO tab. I've try some method but no one of them don't work for me. Well let's start with started.
In this image in left part it's what I need to do as actionbar and in the right part it's how looks my project right now.
I've try to put that code for add the back button but it don't works:
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setHomeButtonEnabled(true);
Here it's my Activity:
public class TrailActivity extends FragmentActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
Intent intent;
Trail trail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
intent = getIntent();
setContentView(R.layout.trail_fracment_main);
trail = intent.getParcelableExtra("trail");
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setHomeButtonEnabled(true);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
InfoFragments infoFragments = new InfoFragments();
infoFragments.setTrail(trail);
Fragment fragment = infoFragments;
return fragment;
} else if (position == 1) {
return new MapFragments();
} else {
return new WondersFragments();
}
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
Some one told me to try to implement OnBackStackChangedListener and after that he want to put in my code and that:
#Override
public void onCreate(Bundle savedInstanceState) {
//Listen for changes in the back stack
getSupportFragmentManager().addOnBackStackChangedListener(this);
//Handle when activity is recreated like on orientation Change
shouldDisplayHomeUp();
}
#Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0;
getSupportActionBar().setDisplayHomeAsUpEnabled(canback);
}
#Override
public boolean onSupportNavigateUp() {
//This method is called when the up button is pressed. Just the pop back stack.
getSupportFragmentManager().popBackStack();
return true;
}
Also I've try to add and that override method, but again... nothing happen :(
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; goto parent activity.
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I've try and that... but again... I've don't obtain any result :(.
So please guys, if anyone know how can I solve that problem, please show me.. I really need to do that and how much fast is possible.

Updating the contents on tab changed in view pager

I am scracthing my head for past 1 day but unable to find the solution.
In mine application there are two tabs under the toolbar
First tab is USER-TAB
the second one is ADMIN-TAB
In both the tabs there are the listView. When a ListItem on the USER-TAB is clicked a dialog appears and user take some action.
Now after this when the ADMIN-TAB is Selected the Admin should get refreshed with new sets of data. But It's not. On selecting the ADMIN-TAB the onResume() method and everyting is getting called but it is not able to update the list.
I wont be able to write the Whole code, I am giving some snippet.
Basically I have taken the code from this link
https://github.com/codepath/android_guides/wiki/Sliding-Tabs-with-PagerSlidingTabStrip
In My Main Activity I have written the OpPageChangeListener.
public class MaterialTab extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.material_main_sample);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new SampleFragmentPagerAdapter(getSupportFragmentManager()));
// Give the PagerSlidingTabStrip the ViewPager
PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
// Attach the view pager to the tab strip
tabsStrip.setViewPager(viewPager);
tabsStrip.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if(position == 0){
MileUserFragment userFragment = new MileUserFragment();
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(userFragment);
ft.attach(userFragment);
ft.commit();
} if(position == 1){
MileAdminFragment adminFragment = new MileAdminFragment();
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(adminFragment);
ft.attach(adminFragment);
ft.commit();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
OnPageSelected You can see I am detaching and reattaching the fragment.Everything is working fine. Both Fragments OnResume() are getting called but the List is not getting changed. I don't undrstand why
For additional assistance i am adding snippet one Fragment. Hope this will give some Idea where i might be going wrong
public class MileUserFragment extends Fragment {
#Override
public void onResume() {
super.onResume();
new GetAdminDbTask().execute();
if(!internetUtil.isConnectedToInternet(getActivity())){
mSwipeRefreshLayout.setRefreshing(false);
mSwipeRefreshLayout.setEnabled(false);
}
}
public class GetAdminDbTask extends AsyncTask<Admin, Void, String> {
#Override
protected String doInBackground(Admin... parmas) {
_adminList = shipmentDbHandler.getAllAdmin();
return "";
}
#Override
protected void onPostExecute(String str) {
mAdminAdapter = new AdminAdapter(getActivity(), _adminList);
adminListView.setAdapter(mAdminAdapter);
mAdminAdapter.notifyDataSetChanged();
// Set the refresh Listener to false after the list has been loaded with new set of data
if (mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
}
if(_adminList.size() > 0 ){
mAdminAdapter = new AdminAdapter(getActivity(), _adminList);
adminListView.setAdapter(mAdminAdapter);
mAdminAdapter.notifyDataSetChanged();
}
}
}
}
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private String tabTitles[] = new String[] { "Tab1", "Tab2" };
private FragmentManager fragmentManager;
public SampleFragmentPagerAdapter(FragmentManager fm) {
super(fm);
this.fragmentManager = fm;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
FragmentTransaction ft = null;
if(position == 0){
MileUserFragment userFragment = new MileUserFragment();
return userFragment;
}
if(position == 1){
MileAdminFragment adminFragment = new MileAdminFragment();
return archiveFragment;
}
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
Haah.. Finally i got an answer to after an heck of losing almost 1 and half days. It might be not completely good answer but atleast it is one of the closest I got.
First of all MainActivity.java looks like:
tabs.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
int scrollPosition = 0;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0){
scrollPosition = 0;
}
if(position == 1){
scrollPosition = 1;
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
if(state == pager.SCROLL_STATE_IDLE){
if(scrollPosition == 0 && application.isActiveAction()){
viewPagerAdapter.notifyDataSetChanged();
application.setActiveAction(false);
}
if(scrollPosition == 1 && application.isArchiveAction()){
viewPagerAdapter.notifyDataSetChanged();
application.setArchiveAction(false);
}
}
}
});
Now what I have done here is I have set OnPageChangeListener and in this I am keeping track of the position whenever the tabs are changing. For my needs what i have done is i have created two boolean variables and setting it when any content on those tab are changing in Application scope. Now when the contents on one tab has been changed or some Action are done I am calling
viewPagerAdapter.notifyDataSetChanged() // Now this is the real gem
after invoking this it will make a call to the ViewPagerAdapter function
#Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE; // This will get invoke as soon as you call notifyDataSetChanged on viewPagerAdapter.
}
Also the Point is your ViewPagerAdapter should extend FragmentStatePageAdapter. Now the Point is
PagerAdapter.POSITION_NONE
will not cache the fragment and reload a new fragment for that tab position.
Basic idea is we should not make or retutn PagerAdapter.POSITION_NONE everytime on sliding of tab since it destroys the cached element and reload the fragment which affects UI performance.
So finally the basic thing is always check that whether on calling viewPagerAdapter.notifyDataSetChanged() the function getItemPosition() should also gets invoked. Hope it will help somebody. For better perfomance you can make changes according to your requirement.
I got the needed breakthrough and understanding from this post : #Louth Answer
Remove Fragment Page from ViewPager in Android
Just put
viewPager.setCurrentItem(tab.getPosition());
in your onTabSelected method like:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

Android: Activity losing link to ViewPager Fragment

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.

Android FragmentActivity/FragmentPagerAdapter and actionBar update onCreateOptionsMenu

I have an activity that uses a fragmentpageradapter to create an ics style actionBar. Each page needs to update the actionBar though. Is there a way I can call onCreateOptionsMenu in my onPageSelected?
I've trimmed a lot of the code out from the example below for simplicity's sake.
public class ListFragmentViewPagerActivity extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.thread_view);
ViewPager pager = (ViewPager) findViewById(android.R.id.list);
pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager()));
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager);
indicator.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
});
}
public class ExamplePagerAdapter extends FragmentPagerAdapter implements TitleProvider{
public ExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return URLS.size();
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new ThreadFragment();
// set arguments here, if required
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public String getTitle(int pos) {
return TITLES.get(pos);
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuinflate = new MenuInflater(this);
menuinflate.inflate(R.menu.thread_menu, menu);
if (type.equals("xda")) {
menu.removeItem(R.id.ss_view);
}
//This worked when I only needed to call it one time. I need to update this menu for each page in my viewPager though.
if (isFav) {
menu.getItem(2).setIcon(R.drawable.fav_ab);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
case R.id.ss_view:
Intent ssi = new Intent(this, SSActivity.class);
ssi.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle b = new Bundle();
ssi.putExtras(b);
startActivity(ssi);
break;
case R.id.restart:
break;
case R.id.fav_ab:
break;
default:
return super.onOptionsItemSelected(item);
}
return false;
}
}
UPDATE
Calling invalidateOptionsMenu() in my onPageSelected() did the trick!
Use invalidateOptionsMenu() but make sure you wrap this in a trycatch if you are supporting anythign below 3.0, as this method does not exist and will crash!
If you want to update your menu on pre 3.0 devices, override the onPrepareOptionsMenu() as well, which will be called everytime the menu is opened.

Categories

Resources