I am trying to create an endless FragmentPagerAdapter , on swipe to replace the adapter with a new one, and depending on which side you swipe, a global variable to increase or decrease, so you can know on what position you are. So I have tried this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(1);
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mViewPager.getCurrentItem() == 0) {
// left
mViewPager.setAdapter(null);
mViewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));
mViewPager.setCurrentItem(1);
MyVar.INST.position--;
} else if (mViewPager.getCurrentItem() == 2) {
// right
mViewPager.setAdapter(null);
mViewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));
mViewPager.setCurrentItem(1);
MyVar.INST.position++;
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
the problem is, even though I have set the offscreenPageLimit to 0, Android still caches the 3 fragment in the memory by default, so when I scroll to the right, the method inside OnPageChangeListener is not being called, therefore the global variable is not being incremented properly....
Any idea how can I fix that?
EDIT: Here is the adapter
private class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return Fragment1.newInstance(MyVar.INST.position + position);
}
#Override
public int getCount() {
return 3;
}
}
So I managed to do it like this, works good
private void setAdapter() {
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(1);
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
if (mViewPager.getCurrentItem() == 0) {
// left
mViewPager.removeAllViews();
//globalVariable--;
setAdapter();
} else if (mViewPager.getCurrentItem() == 2) {
// right
mViewPager.removeAllViews();
//globalVariable++;
setAdapter();
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
And the adapter stays the same
private class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return Fragment1.newInstance(MyVar.INST.position + position);
}
#Override
public int getCount() {
return 3;
}
The main thing that makes it work is the mViewPager.removeAllViews(); which removes the previous fragments, so it doesnt mess up.
Use the globalVariable defined in some other class, singleton for example, to know on which position you are from the start
Related
I am doing swiping application in android. But I got one problem that getItem() method
is calling twice initially. I tried to solve this but I didn’t get solution. please help me
to find out solution. below snippets my code:-
public class DisplayEMIBOFQuestionActivity extends FragmentActivity {
private ViewPager pager;
private int savePosition;
private Context context;
private String fragTag1;
private String fragTag2;
/*
* (non-Javadoc)
*
* #see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.common_emi_bof_display_question);
context = getLayoutInflater().getContext();
if(Helper.isTablet)
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}else
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// Initialise the pager
pager = (ViewPager) findViewById(R.id.viewpager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
/**
* on swiping the viewpager make respective tab selected
* */
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(int position) {}
public void onPageScrolled(int position, float arg1, int arg2) {}
public void onPageScrollStateChanged(int arg0) {
}
});
getPager().setPageTransformer(true, new SwipeAnimation());
}
public ViewPager getPager() {
return pager;
}
public void setPager(ViewPager pager) {
this.pager = pager;
}
public String getFragTag1() {
return fragTag1;
}
public void setFragTag1(String fragTag1) {
this.fragTag1 = fragTag1;
}
public String getFragTag2() {
return fragTag2;
}
public void setFragTag2(String fragTag2) {
this.fragTag2 = fragTag2;
}
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int pos) {
System.out.println("************** "+pos);
Helper.currentQuestion = pos;
if(Helper.randomQuestionList.get(pos).getSubQuestionType().equals(QuestionType.BOF.toString()))
return new DisplayBOFQuestionFragment();
else
return new DisplayEMIQuestionFragment();
}
#Override
public int getCount() {
return Helper.NUMBEROFQUESTIONS;
}
#Override
public CharSequence getPageTitle(int position) {
return super.getPageTitle(position);
}
}
public void setPagerPosition(int pos){
pager.setCurrentItem(pos);
}
}
It gets one fragment and two adjacent ones (here you just have one), so initially will get Tab1 and Tab2 to get ready when you swipe to Tab2, at Tab2 selected will also call getItem for Tab3 to prepare for swipe.
I'm editing the source code of my friend's app and i'm trying to figure out how to deal with fragments. In the app i have an activity with 3 tab and when i click on one of them the selected tab become highlighted. This not happen when i switch from a tab to another doing swiping on the screen. How to edit the code to add this possibility?
public class ViewMyPage extends FragmentActivity{
List<Fragment> fragments = new Vector<Fragment>();
private PagerAdapter mPagerAdapter;
private ViewPager mPager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewmerchant);
Bundle b = new Bundle();
b.putString("id", getIntent().getExtras().getString("id"));
fragments.add(Fragment.instantiate(this,SchedaMerchant.class.getName(),b));
fragments.add(Fragment.instantiate(this,DescrizioneMerchant.class.getName(),b));
fragments.add(Fragment.instantiate(this,ListaRecensioni.class.getName(),b));
this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
mPager = (ViewPager) super.findViewById(R.id.pager);
mPager.setAdapter(this.mPagerAdapter);
final Button button = (Button)findViewById(R.id.buttonscheda);
final Button button2 = (Button)findViewById(R.id.buttondesc);
final Button button1 = (Button)findViewById(R.id.buttonrec);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
mPager.setCurrentItem(0); // go to first tab
}
});
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
mPager.setCurrentItem(1); // go to second tab
}
});
button1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
mPager.setCurrentItem(2); // go to third tab
}
});
}
}
public class PagerAdapter extends FragmentPagerAdapter {
// fragments to instantiate in the viewpager
private List<Fragment> fragments;
// constructor
public PagerAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
// return access to fragment from position, required override
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
// number of fragments in list, required override
#Override
public int getCount() {
return this.fragments.size();
}
}
Solved with this:
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
if (position == 0) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
} else if (position == 1) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
} else if (position == 2) {
button.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button2.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_11));
button1.setBackgroundDrawable(getResources().getDrawable(R.color.transparent_black_hex_8));
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
});
Sorry for my post...
I have a ViewPager that sets up two fragments as swipeable tabs. I am trying to find these fragments in the hosting activity.
I set them up as class global variables:
private SharedBillFragment sharedBill;
private SeparateBillFragment separateBill;
and try to find them in the activity's onStart():
#Override
protected void onStart() {
super.onStart();
findFragments();
}
where findFragments() is (I know this is kind of a hack, but it should work for the moment...):
private void findFragments() {
sharedBill = (SharedBillFragment)
getFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + 0);
separateBill = (SeparateBillFragment)
getFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + 1);
}
But this is not working, the fragments are not found. When i call findFragments() in a method that is called later (following a user interaction), the fragments are found and I can use them. Example:
private void setCountryTip(String selectedCountry) {
findFragments();
sharedBill.setPercentage(getCountryTip(selectedCountry));
separateBill.setPercentage(getCountryTip(selectedCountry));
}
But even when called then, the fragments are only available in the method where findFragments() is called, even though I set them as class global variables.
Best case, I would like to find the fragments when the app is started and store them in class global variables. Any help how to achieve that?
EDIT:
Some more information on how my fragments are setup. In my MainActivity I have:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] mTabTitles = getResources().getStringArray(R.array.tabs);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabsAdapter = new TabsAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.viewPager);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
mViewPager.setAdapter(mTabsAdapter);
for (String tab_name : mTabTitles) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
}
and my TabsAdapter:
public class TabsAdapter extends FragmentPagerAdapter {
final int NUMBER_OF_TABS = 2;
public TabsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new SharedBillFragment();
case 1:
return new SeparateBillFragment();
}
return null;
}
#Override
public int getCount() {
return NUMBER_OF_TABS;
}
}
EDIT: Regarding the NPE, my spinner is setup as follows in the fragment:
private Spinner spCountry;
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
spCountry = (Spinner) getActivity().findViewById(R.id.spCountry);
spCountry.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
mCallback.onCountrySelected(spCountry.getItemAtPosition(pos).toString());
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void setCountry(String country) {
ArrayAdapter spCountryAdapter = (ArrayAdapter) spCountry.getAdapter();
spCountry.setSelection(spCountryAdapter.getPosition(country));
}
The spinner gets its entries via the xml property "android:entries".
Not a very nice and re-usable solution, but since you are using static fragments it could work: make the adapters type Fragment, and initialize the fragments in the activity. Than add the two fragment to the adapter, and in the adapters getItem function only return the corresponding fragment.
Adapter:
public class TabsAdapter extends FragmentPagerAdapter {
List<Fragment> fragments;
public TabsAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int index) {
return fragments.get(index);
}
#Override
public int getCount() {
return fragments.size();
}
}
Activity:
sharedBillFragment = new SharedBillFragment();
separateBillFragment = new SeparateBillFragment();
List<Fragment> fragments = new ArrayList<Fragment>();
fragments.add(sharedBillFragment);
fragments.add(separateBillFragment);
mTabsAdapter = new TabsAdapter(getFragmentManager(), fragments);
mViewPager = (ViewPager) findViewById(R.id.viewPager);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
mViewPager.setAdapter(mTabsAdapter);
Find the spinner in the onCreateView like this:
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment, containter, false);
spCountry = (Spinner) getActivity().findViewById(R.id.spCountry);
...
return v;
}
I am using view-pager.In that I have three tabs : 1. History , 2. Main , 3. Map .
I have stopwatch into main activity.When I press the start and then after stop at that time value of the stopwatch add into the sqlite DB. And into history activity I am fetching the value of stopwatch from DB and store into the listview. It's working perfect.
But now I want the update the History activity when I swipe from the Main > History so After press the stop button,I got the last value into listview of history activity.
My question is how can I update the view on swipe the viewpager?
public class SwipeyTabsSampleActivity extends FragmentActivity {
private static final String [] TITLES = {
"HISTORY",
"MAIN",
"MAP"
};
private SwipeyTabs mTabs;
private ViewPager mViewPager;
//Handler handler=new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipeytab);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabs = (SwipeyTabs) findViewById(R.id.swipeytabs);
SwipeyTabsPagerAdapter adapter = new SwipeyTabsPagerAdapter(this,
getSupportFragmentManager());
mViewPager.setAdapter(adapter);
mTabs.setAdapter(adapter);
mViewPager.setOnPageChangeListener(mTabs);
mViewPager.setCurrentItem(1);
mViewPager.setOffscreenPageLimit(3);
}
private class SwipeyTabsPagerAdapter extends FragmentPagerAdapter implements
SwipeyTabsAdapter, ViewPager.OnPageChangeListener {
private final Context mContext;
ViewPager viewpager;
public SwipeyTabsPagerAdapter(Context context, FragmentManager fm, ViewPager mViewPager) {
super(fm);
this.mContext = context;
viewpager = mViewPager;
//viewpager.setAdapter(this);
viewpager.setOnPageChangeListener(this);
}
#Override
public Fragment getItem(int position) {
Fragment f = new Fragment();
switch (position) {
case 0:
f = History.newInstance(position);
break;
case 1:
f = Main.newInstance(position);
break;
case 2:
f = Map.newInstance(position);
break;
}
return f;
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager pager = (ViewPager) container;
View view = (View) object;
pager.removeView(view);
}
public TextView getTab(final int position, SwipeyTabs root) {
TextView view = (TextView) LayoutInflater.from(mContext).inflate(
R.layout.swipey_tab_indicator, root, false);
view.setText(TITLES[position]);
view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mViewPager.setCurrentItem(position);
}
});
return view;
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int positiion) {
// TODO Auto-generated method stub
}
}
}
Add ViewPager OnPageChangeListener:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// your code here
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
This will affect the changes from one page to another page in view pager.
OnPageChangeListener pagechangelistener =new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
Logger.logMessage("Called first");
pageAdapter.notifyDataSetChanged();
indicator.setCurrentItem(arg0);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Logger.logMessage("Called second");
}
#Override
public void onPageScrollStateChanged(int arg0) {
Logger.logMessage("Called third");
}
};
myViewPager.setOnPageChangeListener(pagechangelistener);
Use this in your page adapter.
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Take one string and add the Getters and setters into your FragmentActivity class.
Like...
String HistoryFragment;
public String getHistoryFragment() {
return HistoryFragment;
}
public void setHistoryFragment(String historyFragment) {
HistoryFragment = historyFragment;
}
Then after we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>).
For the more information check the link Communication between Fragments in ViewPager.
Have you tried implementing OnPageChanged`? You can capture when the user start swiping.
do pager.setOnPageChanged(new ....) and Eclipse will show you the methods you can override.
Then you can override onPageScrollStateChanged(int state)
onPageScrollStateChanged(int state){
if (state==OnPageChangeListener.SCROLL_STATE_DRAGGING){
// update here
}
}
After the device goes on standby, if I call getSupportFragmentManager() I get a FragmentManager that contains fragments not initialised with all their variables set to null.
Here there is some code:
this.mAdapter = new MyAdapter(getSupportFragmentManager());
this.mPager = (ViewPager) findViewById(R.id.pager);
this.mPager.setAdapter(mAdapter);
TabPageIndicator titleIndicator = (TabPageIndicator) findViewById(R.id.titles);
titleIndicator.setViewPager(mPager);
titleIndicator.setOnPageChangeListener(new OnPageChangeListener()
{
#Override
public void onPageSelected(int position)
{
mAdapter.getItem(position).onFocus();
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
#Override
public void onPageScrollStateChanged(int arg0)
{
}
});
This is MyAdapter class:
public static class MyAdapter extends FragmentStatePagerAdapter
{
ArrayList<ExtendedFragment> tabs = new ArrayList<ExtendedFragment>();
String[] titles = new String[] { "FRAG1", "FRAG2", "FRAG3", "FRAG4", "FRAG5", "FRAG6"};
public MyAdapter(FragmentManager fm)
{
super(fm);
tabs.add(new frag1());
tabs.add(new frag2());
tabs.add(new frag3());
tabs.add(new frag4());
tabs.add(new frag5());
tabs.add(new frag6());
}
#Override
public int getCount()
{
return tabs.size();
}
#Override
public ExtendedFragment getItem(int position)
{
return tabs.get(position);
}
#Override
public CharSequence getPageTitle(int position)
{
return titles[position];
}
}
The ExtendedFragment implements the method onFocus(), each fragment override that because i need to do some actions when a tab gets the focus. When I resume the device from standby and onFocus() is fired, if I try to get the View using getView() I get null.
Why my view is null?
You could try overriding onSaveInstanceState method.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mContentFragment = getSupportFragmentManager().getFragment(
savedInstanceState, "mContent");
}
if (mContentFragment == null) {
mContentFragment = new YourFragment();
}
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mContent",
mContentFragment);
}