This is the autogenerated code from android studio when selecting a 3 tabbed layout. The problem is when it starts at the first tab, it will call onCreateView in class PlaceholderFragment. When i switch to the 2nd tab, it calls it again for that tab. Now the problem starts with going back to tab1, it doesn't call onCreateView. Now if i go to tab3 it gets called for that tab, then go back to tab1 it now gets called. So tab1's onCreateView never gets called if i go from tab2 to tab1 but gets called going from tab3 to tab1. I can't figure out why it doesn't destroy this view in that specific sequence only.
I haven't modified this auto-generated code so i'd think it would have worked correctly.
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
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 boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#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) {
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 3 total pages.
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;
}
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
Viewpager has one public method named setOffScreenPageLimit() which indicates the number of pages that will be retained to either side of the current page in the view hierarchy in an idle state.
When you use the default implementation of setOffscreenPageLimit() it is only loading the one fragment which is to the right of it.
For example,
if you are currently on index1, it has index 2 loaded in memory but not index 0, so swiping to left will load a new fragment from scratch. Use setOffScreenLimit(1), setOffScreenLimit(2) etc. it will help clear out your doubts about the concept.
Related
I am trying to detect when a fragment becomes visible on a swipe view, in order to update its content when it does become visible. I am doing it like this.
public class MyFragment extends Fragment {
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) { }
else { }
}
}
The thing is when I go to the page be swipping through it works great but when I select the page in the tab it crashes "Attempt to invoke virtual method".
Please help me, thanks
I have a main activity, and then an activity for each fragment.
Main:
public class Principal extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_principal);
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
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()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#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_principal, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#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) {
}
/**
* 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) {
Fragment fragment = new Fragment();
switch (position) {
case 0:
return fragment = new Config();
case 1:
return fragment = new Saidas();
case 2:
return fragment = new Entradas();
case 3:
return fragment = new Enviar();
case 4:
return fragment = new Historico();
case 5:
return fragment = new Status();
default:
break;
}
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return 6;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_config).toUpperCase(l);
case 1:
return getString(R.string.title_saidas).toUpperCase(l);
case 2:
return getString(R.string.title_entradas).toUpperCase(l);
case 3:
return getString(R.string.title_enviar).toUpperCase(l);
case 4:
return getString(R.string.title_historico).toUpperCase(l);
case 5:
return getString(R.string.title_status).toUpperCase(l);
}
return null;
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_principal, container, false);
return rootView;
}
}
}
and then the fragments are:
public class Entradas extends android.support.v4.app.Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_entradas, container, false);
}
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
run code here....
}
}
There are 2 ways in which you can do this:
From the fragment you can call isVisible();
Return true if the fragment is currently visible to the user. This
means it: (1) has been added, (2) has its view attached to the window,
and (3) is not hidden.
From the parent activity you can do the following:
public boolean checkIsFragVisible() {
Fragment yourFragment = getSupportFragmentManager().findFragmentById(FRAG_HOLDER_ID);
return yourFragment != null && yourFragment.isVisible();
}
I am trying to implement ActionBar tabs in Navigation Drawer item fragment.
But On starting the app, it gets invisible instantly
Here is my MainActivity:
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager ;
switch(position) {
case 0:
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, tabFragment.newInstance()).commit();
break;
case 1:
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
.commit();
break;
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.categorised);
break;
case 2:
mTitle = getString(R.string.individual);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
//getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
/*#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}*/
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
And My Fragment activity
public class tabFragment extends Fragment implements ActionBar.TabListener{
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
public static tabFragment newInstance() {
return new tabFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.testtab, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pagerTest);
mViewPager.setAdapter(mSectionsPagerAdapter);
final ActionBar actionBar = ((MainActivity)getActivity()).getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
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()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
return v;
}
#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) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 3 total pages.
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;
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.testtab1, container, false);
return rootView;
}
}
}
I don't Know why its not working. Any suggestions?
Stuck here for whole day before asking here. Thank you
I figured out that actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS) is deprecated. Instead of that we can use Google I/O 14 app library i.e Toolbar with tabs. It took me 2 days though. Thanks Stack.
Here is the link: Sliding Tabs
I want to replace a Fragment by a new Fragment when an onClick method is called. I wanted to do it this way:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(this);
transaction.addToBackStack(null);
transaction.add(new ChooseCocktailFragment(), null);
transaction.commit();
The only thing that happens is the current Fragment is removed and the new one doesn't show. What am I doing wrong here?
Also, I use a ViewPager and this is the first time for me working with fragments. Usually I would have a Container with its ID but here the ViewPager contains the fragments, therefore I don't know how to use the transaction.replace(...) method.
You should use a FragmentPagerAdapter which is adequate to put Fragments inside ViewPagers.
A complete tutorial from android developer here
EDIT:
First of all, you need to override the getItemPosition of the adapter, and return the POSITION_NONE constant in order to be able to replace pager's fragments.
#Override
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
Then create a listner for handling fragment switching:
public interface MyListener
{
public void onFragmentChange();
}
Your adapter should implements the listner and add some code inside onFragmentChange() method:
public class TabsPagerAdapter extends FragmentPagerAdapter {
private FragmentManager fm;
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
this.fm = fm;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
fragment1 = TopRatedFragment.newInstance(this);
return fragment1;
case 1:
// ...
return fragment2;
case 2:
// ...
return fragment3;
case 3:
// ...
return fragment4;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 4;
}
public void onFragmentChange(){
fm.beginTransaction().remove(fragment1).commit();
fragment1 = NewFragment.newInstance();
notifyDataSetChanged(); // notify the viewpager adapter that content has changed
}
}
Pass an instance of the listner in the fragment you want to remove/replace later :
public class TopRatedFragment extends Fragment {
public static TopRatedFragment newInstance(MyListner listner) {
this.myListner = listner;
return new TopRatedFragment ();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// some logical here ... and when you want to change fragment do this
myListner.onFragmentChange();
}
}
Here is some more explanation of this.
You should also read about FragmentStatePagerAdapter : here
Hope it helps !
You forget hide your fragment after another fragment is added up on your fragment.
Just add more a statement transaction.hide(Your_Fragment) before transaction.commit()
#mansoulx
Here is my code which my answer refers to. Since i implemented it using a tutorial it is very similiar, just Tab names and the content of the tabs changed. I also have 4 tabs, not three - but the problem would be the same:
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
MainActivity.java
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Tab1", "Tab2", "Tab3" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 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));
}
#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) {
}
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) {
}
});
let's say all Fragments would look like this:
Fragment1.java
public class TopRatedFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
}
The thing which should be done now is:
Replace Fragment1 on Tab1 with FragmentNew which should appear in Tab1 too! The OnClick-Event takes place in the fragment1.java for example...
Hi Im new in android and I want ask for help. Im creating new project in android studio and I use navigation Action bar tabs with viewpager. Android studio generate this code. I know work with one activity atc but now I want to learn work with swipe layouts with tabs. My question is: Is possible do more layouts with different items inside this? For example, now I have on every fragment one textview and when I swipe I see any text on every page. But I need for example on page(tab1) layout with textview, on tab2 I need layout edittext, on tab3 I need layout with image. Is this possible with this? Because I can change text but now I have the same layout for all tabs.
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
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 boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
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());
}
#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) {
return PlaceholderFragment.newInstance(position + 1);
}
#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;
}
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
}
In this case you can define 3 separate fragment classes. Then you can return them appropriately in getItem of your SectionsPagerAdapter:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YourFragmentClass1();
case 1:
return new YourFragmentClass2();
case 2:
return new YourFragmentClass3();
}
}
To elaborate on Szymon's answer.
Step 1 Delete the inner class PlaceHolderFragment
Step 2: Create your fragment classes, with corresponding layouts. For example, ImageViewFragment (which extends Fragment of course) and then image_view_fragment_layout.
Step 3 Have ImageViewFragment's onCreateView method inflateimage_view_fragment_layout.
public ImageViewFragment extends Fragment {
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.image_view_fragment_layout,
container, false);
return rootView;
}
Follow these steps for as many tabs you want to add.
Then in the getItem() method follow Szymon's answer. Remember, the tab you want to appear first will be in position 0 and so on.
One more Important thing, in your getCount method:
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
the number returned should reflect the number of tabs you have added.
I've looked at quite a lot of code and can't figure this out. http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
It has to be something simple.
I'm showing most of the code. The error is in the next section.
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
public static final int TAB_COUNT = 3;
public static InputMethodManager inputManager;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
// To control keyboard pop-up
inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
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());
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
This is where my error is.
case 1 of getItem, Type mismatch: Cannot convert from MainActivity.HistoryFragment to Fragment. it is telling me to either change method return type to HistoryFragment or change return type of newInstance() to Fragment. Where I can't do either. Other examples I've seen look almost identical to my code. I have tried with and without passing an argument.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
Fragment tipCalc = new TipCalcFragment();
return tipCalc;
case 1:
// Fragment history = new HistoryFragment();
return HistoryFragment.newInstance(i); //ERROR HERE
case 2:
Fragment stats = new StatsFragment();
return stats;
}
return null;
}
And my HistoryFragment that extends ListFragment. In the end it won't be pulling from the String[] values but from database resources. I just wanted to setup a structure first and see it/play with the layout.
public static class HistoryFragment extends ListFragment {
// public HistoryFragment() {
// }
String[] values = new String[] { ... };
static HistoryFragment newInstance(int num) {
HistoryFragment history = new HistoryFragment();
Bundle args = new Bundle();
args.putInt("num", num);
history.setArguments(args);
return history;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.history, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1,
values));
}
}
I figured it out after getting some sleep. I was importing android.app.ListFragment instead of android.support.v4.app.ListFragment
I think you will have to typecast to fragment before returning. So try this
Fragment history = HistoryFragment.newInstance(i);
return history;