I have an activity that extends FragmentActivity, I use a custom FragmentStatePagerAdapter that extends FragmentStatePagerAdapter, a SlidingTabLayout and a pagerView.
In some cases I want my fragmentActivity to start on a specific (third, if it matters..) tab.
I've tried lots of suggestion I found on SO but non worked. When I tries to use "pager.setCurrentItem(3)" the problem was that onCreateView for that fragment was never called and therefore all objects and values are not assigned properly.
thanks for the help!
EDIT: Adding more info
this is how I init my adapter:
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, NewsTab.class.getName()));
fragments.add(Fragment.instantiate(this, PhotosTab.class.getName()));
fragments.add(Fragment.instantiate(this, AboutTab.class.getName()));
fragments.add(Fragment.instantiate(this, NextTab.class.getName()));
adapter = new ProtestViewPagerAdapter(getSupportFragmentManager(),Titles, NumOfTabs, fragments);
this is my view pager adapter:
public class ProtestViewPagerAdapter extends FragmentStatePagerAdapter {
public final String TAG = "PRTST_V_PGR_ADPTR";
private CharSequence Titles[];
private int NumbOfTabs;
private List<Fragment> fragments;
// Build a Constructor and assign the passed Values to appropriate values in the class
public ProtestViewPagerAdapter(FragmentManager fm, CharSequence mTitles[], int mNumbOfTabs,
List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabs;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
return fragments.get(position);
// switch (position){
// case 0:
// NewsTab news = new NewsTab();
// return news;
// case 1:
// PhotosTab photos = new PhotosTab();
// return photos;
// case 2:
// AboutTab about = new AboutTab();
// return about;
// case 3:
// NextTab next = new NextTab();
// return next;
// default:
// return null;
// }
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return this.Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return this.NumbOfTabs;
}
}
each of the tabs implements FragmentInterface that only have
void fragmentBecameVisible();
and the "tabs" also extends "MyBaseTab" that extends android.support.v4.app.Fragment
Related
I have viewpager that has 4 fragments.
I have set the offscreenPageLimit to 4 and did not override getItemPosition of the adapter because I don't want them to be re-created every time when I change tabs.
Now, there will be a scenario when I want a particular fragment to be re-created (it means to call onCreateView).
That is before I select or when I select that fragment again.
How to do this?
Please try this adapter. This recover to re-create fragment again.
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private Fragment[] fragments;
private String[] titleList;
private int index;
public ViewPagerAdapter(FragmentManager fm, String[] titleList){ // titleList is list of title of fragments
super(fm);
fragments = new Fragment[titleList.length];
this.titleList = titleList;
}
#Override
public Fragment getItem(int position) {
Fragment fragment;
if (fragments[position] == null){
YourFragment yourFragment = new YourFragment();
fragment = yourFragment;
fragments[position] = fragment;
return fragment;
}else{
return fragments[position];
}
}
#Override
public int getCount() {
return titleList.length;
}
#Override
public CharSequence getPageTitle(int position) {
return titleList[position].toUpperCase();
}
}
I've a ViewPager (Parent ViewPager) in my activity with 4 fragments. One of the fragments implements a sliding ViewPager (Child ViewPager) with automatic sliding.
When I swipe the parent ViewPager to, say, tab 3 and then I go back to the first fragment which contains the sliding ViewPager, some of the slide disappears and some of it stays. When I slide the ViewPager (the child ViewPager) back and forth couple of times, it gets restored to its original state.
I assume the fragment state of the sliding view pager is getting lost when the parent ViewPager is being slid.
Here's the parent ViewPager's adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Here's the child ViewPager's adapter (slider):
class sliding_PageAdapters extends FragmentPagerAdapter {
int mNumOfTabs;
public sliding_PageAdapters(FragmentManager fm, int numTabs) {
super(fm);
this.mNumOfTabs = numTabs;
}
#Override
public void destroyItem(ViewGroup viewPager, int position, Object object) {
viewPager.removeView((View) object);
}
#Override
public Fragment getItem(int position) {
Bundle ar = new Bundle();
FragmentHomeImages fragment = new FragmentHomeImages();
switch (position) {
case 0:
ar.putString("number", "0");
fragment.setArguments(ar);
return fragment;
case 1:
ar.putString("number", "1");
fragment.setArguments(ar);
return fragment;
case 2:
ar.putString("number", "2");
fragment.setArguments(ar);
return fragment;
case 3:
ar.putString("number", "3");
fragment.setArguments(ar);
return fragment;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
The child ViewPager is being called with getChildFragmentManager() here:
sliding_pagerAdapter = new sliding_PageAdapters(getChildFragmentManager(), 4);
And the parent ViewPager is being called with getSupportFragmentManager() here:
adapter = new ViewPagerAdapter(getSupportFragmentManager());
I can think of one problem. On the parent viewpager call setOffscreenPageLimit(limit).
here limit is the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed. So set the appropriate limit based on your use-case.
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MyAdapter(fragmentManager));
viewPager.setOffscreenPageLimit(2);
My Activity Layout like this,
Activity contains ViewPager1 that contains two fragments (Fragment1 and Fragment2) , Fragment1 contains ViewPager2 ,ViewPager2 contains 3 Fragments
the problems is these 3 Fragments Layout not shown even they exist on ViewPager.
I'm sure they added to ViewPager Adapter because when I debug it I can see them on ViewPager's Adapter
public class ViewPager1Adapter extends FragmentPagerAdapter {
private Context context;
private ArrayList<Fragment> fragments;
private String[] titles;
public ViewPager1Adapter(Context context, FragmentManager fragmentManager, ArrayList<Fragment> fragments) {
super(fragmentManager);
this.context = context;
this.fragments = fragments;
titles = new String[2];
titles[0] = context.getString(R.string.fragment1);
titles[1] = context.getString(R.string.fragment2);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
ViewPager2 Adapter is same like ViewPager1
fragments.add(fragment21);
fragments.add(fragment22);
fragments.add(fragment23);
viewPager2Adapter = new ViewPager2Adapter(getActivity(),
getActivity().getSupportFragmentManager(), fragments);
vp2.setAdapter(viewPager2Adapter);
the problem is Fragment21 , Fragment22 and Fragment23 Layout is not shown?
You have to update below line:
ViewPager1Adapter viewPager1Adapter = new viewPager1Adapter(getActivity(), getActivity().getSupportFragmentManager(), fragments);
Reason: You are calling wrong ViewPagerAdapter.
Also you should update your constructor of adapter, because you are having 2 string for title so you should add third string for third fragment.
public ViewPager1Adapter(Context context, FragmentManager fragmentManager, ArrayList<Fragment> fragments) {
super(fragmentManager);
this.context = context;
this.fragments = fragments;
titles = new String[3];
titles[0] = context.getString(R.string.fragment1);
titles[1] = context.getString(R.string.fragment2);
titles[2] = context.getString(R.string.fragment3);
}
Hope this will help you.
I have a FragmentActivity with two Fragments in it and a sliding tab layout:
String titles[] = new String[] {"Tab One", "Tab Two"};
int numTabs = titles.length;
EventAdapter adapter = new EventAdapter(getSupportFragmentManager(), titles, numTabs);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
SlidingTabLayout sliding_tabs = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
sliding_tabs.setDistributeEvenly(true);
sliding_tabs.setViewPager(pager);
With the FragmentPagerAdapter:
private class EventAdapter extends FragmentPagerAdapter {
private List<String> titles;
private int numTabs;
public void addTab (String title) {
this.titles.add(title);
this.numTabs++;
this.notifyDataSetChanged();
}
public EventAdapter(FragmentManager fm, List<String> mTitles, int mNumTabs) {
super(fm);
this.titles = mTitles;
this.numTabs = mNumTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 2:
return new FragThree();
case 1:
return new FragTwo();
default:
return new FragOne();
}
}
#Override
public String getPageTitle(int position) {
return titles.get(position);
}
#Override
public int getCount() {
return numTabs;
}
}
Some time down the line, I would like to dynamically add the third tab to this layout. Is there a way to do this in code? As you can see, I already have the PagerAdapter set up to catch the third tab. I just need to load it in...
You need to add this method to your adapter EventAdapter :
public void addTab (String title) {
this.titles.add(title);
// this is the variable returned from getCount method
this.numbTabs++;
this.notifyDataSetChanged();
}
Main purpose is to add the tab and call notifydatasetchanged.
Now call addTab on this adapter's object and tab will be added.
after addTab do sliding_tab.setViewPager(this.pager);
Please accept if this solves the purpose.
I followed these guidelines to create a Sliding tab layout with fragments. The problem is that I want to dynamically add a tab to the SlidingTabLayout. The following code creates a fragment but it isn't displayed. How can i attach it to the SlidingTabLayout?
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
tableFragment = (ReportTableFragment) adapter.getItem(1);
fragmentTransaction.replace(R.id.pager, tableFragment, tableFragment.getClass().getName());
fragmentTransaction.commit();
This is my ViewPagerAdapter class
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
//ReportMapFragment reportMapTab = new ReportMapFragment();
//return reportMapTab;
SupportMapFragment mapTab = new SupportMapFragment();
return mapTab;
}
else
{
return ReportTableFragment.newInstance(1);
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
}
The solution is pretty easy :)
You should add this methods to your 'ViewPagerAdapter' and change the CharSequence by this
List<String> titles = new ArrayList<String>();
Now the constructor should be:
public ViewPagerAdapter(FragmentManager fm, List<String> mTitles, int mNumbOfTabsumb) {
super(fm);
this.titles = mTitles;
this.numbOfTabs = mNumbOfTabsumb;
}
Methods to add to the 'ViewPagerAdapter':
public void addTab (String title) {
this.titles.add(title);
this.numbOfTabs++;
this.notifyDataSetChanged();
}
public void deleteTab (int position) {
this.titles.remove(position);
this.numbOfTabs--;
this.notifyDataSetChanged();
}
And from your activity or wherever you call the SlidingTabLayout:
this.mAdapter.addTab("NewTab"); // add a new tab
this.mAdapter.deleteTab(0); // or delete a current tab
this.mTabs.setViewPager(this.mPager); // don't forget this line, is the key
Pay attention to the 'getItem' method in your 'ViewPagerAdapter' cause now you are adding tabs dynamically ;)
I.