I have 6 Fragments within an activity that I created as
I want to swipe from one to the other and need them to not being dismissed but onyl hide/show y the viewpager.
Is there a way to derive a viewpager class or a SectionsPagerAdapter to do that.
I already add
mViewPager.setOffscreenPageLimit(6);
but it didn't work. When swiping from the 4th fragment to 3rd or to 5th, the app crashes.
Relevant parts of my code simpified and renamed Fragment classes to get the code readable:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// create the fragment once for all !
if (savedInstanceState == null) {
fragment1 = Fragment1.newInstance(1);
fragment2 = Fragment2.newInstance(2);
fragment3 = Fragment3.newInstance(3);
fragment4 = Fragment4.newInstance(4);
fragment5 = Fragment5.newInstance(5);
fragment6 = Fragment6.newInstance(6);
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(6);
});
public static class Fragment1 extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public Fragment1() {
}
public static Fragment1 newInstance(int sectionNumber) {
Fragment1fragment = new Fragment1();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
fragment.setRetainInstance( true);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_1, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
// "Main Frag"
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
#Override
public void onResume() {
super.onResume();
// The activity is about to become visible again, recalcule
}
}
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);
switch (position)
{
case 0 : return fragment1; //instead of Fragment1.newInstance(1);
case 1 : return fragment2;
case 2 : return fragment3;
case 3 : return fragment4;
case 4 : return fragment5;
case 5 : return fragment6;
default: return null;
}
}
#Override
public int getCount() {
// Show 6 total pages.
return 6;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
case 3:
return "SECTION 4";
case 4:
return "SECTION 5";
case 5:
return "SECTION 6";
}
return null;
}
}
Extend your section pager adapter by FragmentSatePagerAdaper
And set
mViewPager.setOffscreenPageLimit(6);
Related
This is my fragment which is in navigation menu.
class MirandaFragment extends Fragment {
protected View view;
FragmentPagerAdapter adapterViewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.miranda, container, false);
ViewPager vpPager = (ViewPager) view.findViewById(R.id.vpPager);
adapterViewPager = new MyPageAdapter(getFragmentManager());
vpPager.setAdapter(adapterViewPager);
return view;
}
}
This is the adapter where I has set two fragments EngMiranda and SpaMiranda.
class MyPageAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 2;
public MyPageAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages.
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for a particular page.
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return EngMiranda.newInstance("Fragment 1", getCount());
case 1:
return SpaMiranda.newInstance("Fragment 2", getCount());
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "English";
case 1:
return "Spanish";
default:
return null;
}
}
}
After app gets open for first time then I am able to open the fragment and view the tab fragments in it but when we open that fragment for second time then adapter is not displaying.
On tab, I have attached five fragments.Till 3rd fragment navigation is fine but when going to 4th and 5th fragment directly or by swiping, app is getting crashed.
This is my main activity.
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Videos"));
tabLayout.addTab(tabLayout.newTab().setText("Games"));
tabLayout.addTab(tabLayout.newTab().setText("Maps"));
tabLayout.addTab(tabLayout.newTab().setText("Quizze"));
tabLayout.addTab(tabLayout.newTab().setText("Discussion"));
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
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;
}
#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(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm, int tabCount) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Videos tab1 = new Videos();
return tab1;
case 1:
Notes tab2 = new Notes();
return tab2;
case 2:
MindMaps tab3 = new MindMaps();
return tab3;
case 3:
Quizze tab4 = new Quizze();
return tab4;
case 5:
Discussion tab5 = new Discussion();
return tab5;
}
return null;
}
#Override
public int getCount() {
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
case 3:
return "SECTION 4";
case 4:
return "SECTION 5";
}
return null;
}
}
}
This is my fragment class which is right now same for all the five fragments except the class name).
public class Videos extends android.support.v4.app.Fragment {
public static Videos newInstance() {
Videos fragment = new Videos();
return fragment;
}
public Videos() {
}
Button ClickMe;
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.video, container, false);
ClickMe = (Button) rootView.findViewById(R.id.button);
tv = (TextView) rootView.findViewById(R.id.textView2);
ClickMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(tv.getText().toString().contains("Hello")){
tv.setText("Hi molu");
}else tv.setText("Hello");
}
});
return rootView;
}
} // This is the end of our MyFragments Class
Case 4 is missing in your adapter. Add the Case 4 instead of 5 then it will work fine.
I have two fragments and want to show them as tab view.But Don"t know where to add those in the below code. These are the code when you select "tabbed activity" in android studio project.
public class MainActivity extends AppCompatActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 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.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#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;
}
#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";
public PlaceholderFragment() {
}
/**
* 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;
}
#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(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* 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.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 3 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Demo";
case 1:
return "SECTION 2";
}
return null;
}
}
}
Fragment class
public class Fragment1 extends Fragment {
public static Fragment1 newInstance() {
Fragment1 fragment = (Fragment1) new Fragment();
return fragment;
}
public Fragment1() {
}
Button ClickMe;
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
ClickMe = (Button) rootView.findViewById(R.id.button);
tv = (TextView) rootView.findViewById(R.id.textView2);
ClickMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(tv.getText().toString().contains("Hello")){
tv.setText("Hi");
}else tv.setText("Hello");
}
});
return rootView;
}
} // This is the end of our Fragment1 Class
This is the place where you need to get your fragment to the specific tab respectively.
#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);
}
Use a switch case statement for the choosen position and get the fragment in tab.
switch (position) {
case 0:
// first fragment activity
return new firstfragment();
case 1:
// second fragment activity
return new secondFragment();
case 2:
// third fragment activity
return new thirdFragment();
}
return null;
}
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).
switch (position) {
case 0:
Fragment1 tab1 = new Fragment1();
return tab1;
case 1:
Fragment2 tab2 = new Fragment2();
return tab2;
// return PlaceholderFragment.newInstance(position + 1);
}
return null;
}
Just changed the above code like this and in Fragment1 extends public class
Fragment1 extends android.support.v4.app.Fragment
First you have to specify how many tabs you are going to use with getCount() method:
#Override
public int getCount() {
int numberOfTabs = 3;
return numberOfTabs;
}
Then, you have to create your fragments your own and add them in getItem(int position) method like this:
#Override
public Fragment getItem(int position)
switch(position){
case 0:
return new YourFirstFragment();
case 1:
return new YourSecondFragment();
case 2:
return new YourThirdFragment();
default:
return new SomeFragment();
}
}
Then you will change the tab names using getPageTitle(int position) method like this:
#Override
public CharSequence getPageTitle(int position)
switch(position){
case 0:
return "First";
case 1:
return "Second";
case 2:
return "Third";
default:
return "Some";
}
}
If I ave an activity with a viewPAger on it and two sets of data that I want to display, is it best to have one fragment and load information into textViews based on position passed from activity or better to create more than one fragment and load the one needed?
Any help is greatly appreciated.
public class testFragment extends Fragment {
private static final String ARG_PAGE = "pageNumber";
private static final int DEFAULT_INT = 0;
TextView header, sd1;
int h1, page = 0;
public testFragment (){
}
public testFragment newInstance(int pageNumber) {
testFragment fragment = new testFragment ();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
page = getArguments().getInt(ARG_PAGE);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_high_scores_page, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
header = (TextView) getActivity().findViewById(R.id.modes_header);
sd1 = (TextView) getActivity().findViewById(R.id.stat_det_1);
switch (page) {
case 1:
header.setText(R.string.easy_mode);
h1 = DEFAULT_INT;
sh1 = DEFAULT_INT;
sd1.setText(String.valueOf(h1));
break;
case 2:
header.setText(R.string.medium_mode);
h1 = DEFAULT_INT + 1;
sh1 = DEFAULT_INT + 1;
sd1.setText(String.valueOf(h1));
break;
default:
header.setText(R.string.action_restart);
h1 = DEFAULT_INT;
sh1 = DEFAULT_INT;
sd1.setText(String.valueOf(h1));
break;
}
}
public void setTextViewInfo(){
sd1.setText(String.valueOf(h1));
}
}
Or would it be better to send the information from my activity and load one or multiple fragments instead?
public class testActivity extends FragmentActivity {
private static final int NUM_PAGES = 8;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testActivity);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.high_scores_pager);
mPagerAdapter = new testActivity (getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
super.onBackPressed();
} else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
private class testActivityAdapter extends FragmentStatePagerAdapter {
public testActivityAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
testFragment tf1 = new testFragment ();
notifyDataSetChanged();
return easy.newInstance(position);
case 1:
testFragment2 tf2 = new testFragment ();
notifyDataSetChanged();
return medium.newInstance(position);
default:
testFragment d = new testFragment ();
return d.newInstance();
}
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
edit:
In my adapter, I just tried
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return HighScoresEasyFragment.newInstance(position);
case 1:
return HighScoresMediumFragment.newInstance(position);
case 2:
return HighScoresExpertFragment.newInstance(position);
case 3:
return HighScoresBrainFartFragment.newInstance(position);
case 4:
return HighScoresClassicFragment.newInstance(position);
case 5:
return HighScoresPuzzleFragment.newInstance(position);
case 6:
return HighScoresPerfectFragment.newInstance(position);
case 7:
return HighScoresPowerFragment.newInstance(position);
default:
return HighScoresEasyFragment.newInstance(position);
}
ugh, but it didn't load anything... my constructor is now...:
public static HighScoresEasyFragment newInstance(int pageNumber) {
HighScoresEasyFragment fragment = new HighScoresEasyFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
return fragment;
}
It loaded the first page's header but no data and it didn't load anything for second to 8th fragments...
You should call notifyDataChanged() from your activity using your adapter reference. Basically notifyDataChanged just tells all your fragments in your adapter that data has changed and they should refresh themselves. Remove notifyDataChanged from your getItem() method and put it when you change data in your activity.
Right now i'm trying to program an android-application with a navigation drawer and swipe views. When selecting "Timetable" in the navigation drawer, the app opens a swipe view with 6 pages with the page number on every page.
The problem is that - when re-selecting the page "Timetable" in the navigation drawer - the pages 5 and 6 are displayed but the content (fragment) won't load.
I used the code of the swipe view-example: http://developer.android.com/training/implementing-navigation/lateral.html
This should be the fragment with the swipe views:
public class Timetable extends Fragment {
ViewPager mViewPager;
SectionsPagerAdapter mSectionsPagerAdapter;
public TimeTable() {
// Empty constructor required for fragment subclasses
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.screen_stundenplantag,
container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(this.getActivity()
.getSupportFragmentManager());
mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
return rootView;
}
Here's the class SectionsPagerAdapter:
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 = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// Show 6 total pages.
return 6;
}
#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);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
case 4:
return getString(R.string.title_section5).toUpperCase(l);
case 5:
return getString(R.string.title_section6).toUpperCase(l);
}
return null;
}
}
And last but not least here's the DummySectionFragment-class:
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static String ARG_SECTION_NUMBER = "";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,
container, false);
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.append("Page "
+ Integer.toString(getArguments()
.getInt(ARG_SECTION_NUMBER)));
Log.i(this.getClass().getSimpleName(),String.valueOf(getArguments().get(DummySectionFragment.ARG_SECTION_NUMBER)));
switch (getArguments().getInt(ARG_SECTION_NUMBER)) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
}
return rootView;
}
}