Fragments not updating in viewpager - android

I am pretty new to ViewPager and adapter world in android. I have seen this issue asked many times but did not quite understand so hoping for a simplified answer :).
I have a ViewPager with 3 tabs and each tab has a fragment. By default the user first sees tab2 where he gives some imput to generate a string. this string then needs to be taken in tab3 which generates a qr code from it.
the string from tab 2 is updated to a class and tab3 takes the string from there.
My Problem is that when i move from tab2->tab3 the qr code is not generated. But when i go tab2->tab1->tab3 it is generated. I am guessing it retains my old fragment .
Below are my class codes. Could you please let me know why is this viewpager behaviour so.
my FragementActivity class:
public class ConfigExchangeMain extends FragmentActivity {
FragmentPagerAdapter adapterViewPager;
SampleFragementPagerAdapterExchange adapter;
String sent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.config_exchange_main);
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
adapter=new SampleFragementPagerAdapterExchange(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
}
}
My Pager Adapter looks like
public class SampleFragementPagerAdapterExchange extends FragmentStatePagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[]{"CONTACTS", "HOME", "QR+SCAN"};
private ConfigDetail context;
public SampleFragementPagerAdapterExchange(FragmentManager fm) {
super(fm);
//this.context = context;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 1:
return new ConfigExchangeNFR();
case 0:
return new ConfigExchangeHome();
case 2:
return new ConfigExchangeQR();
default:
return new ConfigExchangeQR();
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
and my fragment in tab3 that is not updating:
public class ConfigExchangeQR extends Fragment {
ImageView iQRCode ;
int iQRDimension;
Button bScan;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FacebookSdk.sdkInitialize(getActivity().getApplicationContext());
View view1 = inflater.inflate(R.layout.config_exchange_qr, container, false);
iQRCode = (ImageView)view1.findViewById(R.id.qrCode);
iQRDimension = 900;
String FinalQRCode = KeyValueDb.getPrefFinalVCard(getActivity());
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(FinalQRCode, null,
contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), iQRDimension);
try {
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
iQRCode.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
bScan = (Button)view1.findViewById(R.id.scan_qr);
bScan.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
}
});
return view1;
}
}

In ConfigExchangeMain class:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Fragment fragment= adapter.getItem(position);
if(fragment instanceof ConfigExchangeQR ){
((ConfigExchangeQR)fragment).update();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
#Override
public void onDestroy() {
super.onDestroy();
viewPager.clearOnPageChangeListeners();
}
Add this method to your ConfigExchangeQR fragment
public class ConfigExchangeQR extends Fragment {
...
public void update(){
String FinalQRCode = KeyValueDb.getPrefFinalVCard(getActivity());
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(FinalQRCode, null,
contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), iQRDimension);
try {
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
iQRCode.setImageBitmap(bitmap);
} catch (WriterException e) {
}
}
}

When you are currently in your second tab. The first and the third tab are preloaded (because the animation is smoother). When you switch to the first tab the third tab is unloaded -> so after switching back to the third tab it is recreated and it works for you.
The 3rd tab onCreateView is called before the 2nd tab is done, thats why it is not working. Try implementing logic inside the onResume() - to make sure it is always called when the focus is back on the fragment.
Hope this helps...
Cheers

Related

View pager skipping to irregular position when I click button in second fragment android?

I am using view pager in activity and the sequence is - when I click the next button in first page, it should go to the second page. If I click the button in second page, it should go to third and so on. But my current app is behaving weird, i.e, When I click next button in second page, it goes to fourth page. Once again when I click first button in first page, it jumps to third page and so on..
Here is code.
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_act);
setViewPager();
/*pager.setPageTransformer(true, new ZoomPageTransformer());
pager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager()));
pager.post(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(position); //don't know how to use this from fragment
}
});*/
}
private void setViewPager() {
pager = (ViewPager) findViewById(R.id.viewPager);
FragmentManager fm = getSupportFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(fm);
pager.setAdapter(adapter);
}
public void setCurrentItem(int selectedPosition) {
pager.setCurrentItem(selectedPosition, true);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FirstPager.newInstance();
case 1:
return SecondPager.newInstance();
case 2:
return ThirdPager.newInstance();
case 3:
return FourthPager.newInstance();
case 4:
return FifthPager.newInstance();
case 5:
return SixthPager.newInstance();
default:
return null;
}
}
#Override
public int getCount() {
return 6;
}
}
FirstPager:
public class FirstPager extends Fragment {
private ImageView slideArrow;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_pager, container, false);
return v;
}
public static FirstPager newInstance() {
FirstPager fragment = new FirstPager ();
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUI();
}
private void initUI() {
slideArrow = (ImageView) getActivity().findViewById(R.id.next_arrow);
slideArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ViewPagerActivity)getActivity()).setCurrentItem (1);
}
});
}
}
Similarly in other fragments, I gave currentItem as 2,3,4,5 and 6. But it’s position behavior is not correct.
I referred some post but how in my case, how I will apply for a method to pass from fragment to make the position to work correctly?
I think the best approach would be this:
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
slideArrow = (ImageView) getActivity().findViewById(R.id.next_arrow);
Are you sure, you're calling this correctly? You're not.
You're calling findViewById of the arrow inside your activity. A ViewPager works by loading this page, and pre-loading next and previous pages for smooth swipe. And when you click the button on your 1st page, the last loaded page's (in your case 2nd page's) button click event gets called.
You must use the arrow button in each of your fragments
You can do something like this:
public class FirstPager extends Fragment {
private ImageView slideArrow;
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.first_pager, container, false);
return v;
}
public static FirstPager newInstance() {
FirstPager fragment = new FirstPager ();
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUI();
}
private void initUI() {
slideArrow = (ImageView) v.findViewById(R.id.next_arrow); // Note the difference in this line.
slideArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ViewPagerActivity)getActivity()).setCurrentItem (1);
}
});
}
}
You can do two things here:
Firstly,Your viewpager has a override method onPageSelected() which return the select page positon. using this poistion element get the view and bind your button there and write listener there itself and write viewpager.setCurrentItem(i++); //if i is ur current position,but be sure to check if it is the last item.
secondly,you hold the position of the current fragment and
((ViewPagerActivity)getActivity()).setCurrentItem (next_frag_pos);
This code try working perfect.
public class ViewPagerActivity extends FragmentActivity {
private ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_act);
setViewPager();
/*pager.setPageTransformer(true, new ZoomPageTransformer());
pager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager()));
pager.post(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(position); //don't know how to use this from fragment
}
});*/
}
private void setViewPager() {
pager = (ViewPager) findViewById(R.id.viewPager);
FragmentManager fm = getSupportFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(fm);
pager.setAdapter(adapter);
}
public void setCurrentItem(int selectedPosition) {
pager.setCurrentItem(selectedPosition, true);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirstPager();
case 1:
return new SecondPager();
case 2:
return new ThirdPager();
case 3:
return new FourthPager();
case 4:
return new FifthPager();
case 5:
return new SixthPager();
default:
return null;
}
}
#Override
public int getCount() {
return 6;
}
}
}

getItem in FragmentStatePagerAdapter never called when instantiating from a Fragment

I'm using a Fragment on my Activity that will have a picture "swiper". I've created a FragmentStatePagerAdapter which I'm trying to call from this Fragment and for some reason my getItem() method is never being called.
I've searched and found that I need to use getChildFragmentManager() when instantiating my FragmentStatePagerAdapter because I'm calling it from a Fragment. I've tried this as well as getSupportFragmentManager() with no luck from either.
Any ideas?
here's my Fragment that I'm using on my MainActivity with the method that shoudl setup the FragmentStatePagerAdapter:
public class PhotoFlipper extends Fragment {
// properties and fields
// primitive types
String currentImage;
int friendShareType = 0;
ImageView share;
ViewPager pager;
PhotoFlipperItemAdapter pagerAdapter;
LatLng itemPosition;
Activity activity;
FragmentActivity fragActivity;
public ArrayList<MarkerModel> picsAndVids;
// end properties and fields
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View photoFlipperFragmentView = inflater.inflate(R.layout.photo_flipper_layout, container, false);
InitializeFragment(photoFlipperFragmentView);
return photoFlipperFragmentView;
}
private void InitializeFragment(View photoFlipperFragmentView) {
activity = getActivity();
fragActivity = (FragmentActivity)activity;
pager = (ViewPager)photoFlipperFragmentView.findViewById(R.id.photoflipper_pager);
share = (ImageView)photoFlipperFragmentView.findViewById(R.id.photoflipper_share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
IPictureFlipper iPictureFlipper = (IPictureFlipper)activity;
iPictureFlipper.ShareVideoOrImage(friendShareType, itemPosition, currentImage);
}
});
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
pager.setVisibility(View.GONE);
}
}
public void SetTappedPicture(int index) {
pagerAdapter = new PhotoFlipperItemAdapter(getChildFragmentManager(), picsAndVids, picsAndVids.size());
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(index);
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
}
});
}
}
And here's my FragmentStatePagerAdapter:
public class PhotoFlipperItemAdapter extends FragmentStatePagerAdapter {
ArrayList<MarkerModel> _markers;
int NUM_PAGES;
String TAG = "home";
public PhotoFlipperItemAdapter(FragmentManager fm, ArrayList<MarkerModel> markers, int numpages){
super(fm);
Log.d(TAG,"in adapter in constructor");
_markers = markers;
NUM_PAGES = numpages;
}
#Override
public Fragment getItem(int position) {
Log.d(TAG,"in adapter in get item");
Fragment fragment = PhotoFlipperItemFragment.create(position, _markers);
return fragment;
}
#Override
public int getCount() {
Log.d(TAG,"in adapter in get count: "+NUM_PAGES);
return NUM_PAGES;
}
}
logcat is showing me that NUM_PAGES is > 0 so that's not my issue. I see my log in the constructor and in getCount() but nothing in getItem().
TIA
I got this sorted out. I was hiding my fragment in my InitializeActivity() right after I added it to my FragmentManager so it was never fully building the Fragment with the ViewPager etc.
I'm going to have to come up with a different solution for hiding/showing the fragment but that was my problem.

Refresh ViewPager's fragments on swipe

I want to use a viewpager to display information from a stack of objects.
I have a viewpager with 4 fragments and I want that every time I swipe the viewpager to another fragment the non visible fragments pop/peek an object from the stack.
I already tried some stuff. I was trying to listen to page changes using OnPageChangeListener()and find some way to update the fragment content from inside the activity. I didn't manage to do that.
Here is my adapter:
public class PagerAdapter_Browse extends FragmentPagerAdapter {
FragmentManager mManager;
public PagerAdapter_Browse(FragmentManager fm) {
super(fm);
mManager = fm;
}
#Override
public Fragment getItem(int arg0) {
switch (arg0) {
case 0:
return new FragmentBrowseOne();
case 1:
return new FragmentBrowseTwo();
case 2:
return new FragmentBrowseThree();
case 3:
return new FragmentBrowseFour();
default:
break;
}
return null;
}
#Override
public int getCount() {
return 4;
}
}
One of my fragments (all look more a less the same):
public class FragmentBrowseOne extends Fragment {
ImageView main_img;
View view;
public FragmentBrowseOne(){
setArguments(new Bundle());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle bundle = getArguments();
BitmapDrawable profilePic;
view = inflater.inflate(R.layout.fragment_browse_one, container, false);
main_img = (ImageView) view.findViewById(R.id.main_img);
Bitmap temp = bundle.getParcelable("object");
profilePic = new BitmapDrawable(getResources(), temp);
main_img.setBackground(profilePic);
main_img.setScaleType(ImageView.ScaleType.CENTER_CROP);
return view;
}
}
And here is part of my activity:
viewpager = (ViewPager) findViewById(R.id.pager_browser);
padapter = new PagerAdapter_Browse(getSupportFragmentManager());
PagerAdapter wrappedAdapter = new InfinitePagerAdapter(padapter);
viewpager.setAdapter(wrappedAdapter);
viewpager.setId(R.id.pager);
viewpager.setOffscreenPageLimit(1);
viewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
FragmentBrowseOne fragment = new FragmentBrowseOne();
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.mipmap.samplegirl4);
fragment.getArguments().putParcelable("object", pic);
}
});
Use SetArguments and pass it in bundle for every fragment. Arguments must contain new object in which required changes are made.
Use constructor
public FragmentNumber(){
setArguments(new Bundle());
}
Return Fragment by using below method
FragmentNumber fragment = new FragmentNumber();
fragment.getArguments().putSerializable("object", newobject);
This will refresh data inside fragment whenever page changed.

ViewPager recreate fragments all the time

I am using ViewPager with my fragments. All fragments has animation and it does not work when switching back maybe because ViewPager saves somehow state of near Fragments, do you have some idea how to avoid it?
getItemPosition() doesn't make anything in this case
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return GetStartedOneFragment.newInstance();
case 1:
return GetStartedTwoFragment.newInstance();
case 2:
return GetStartedThreeFragment.newInstance();
case 3:
return GetStartedFourFragment.newInstance();
case 4:
return GetStartedFiveFragment.newInstance();
case 5:
return GetStartedSixFragment.newInstance();
default:
return GetStartedOneFragment.newInstance();
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
I used a Fragment as a slider content, see the sample code below. Feel free to ask more details if required.
I have 4 flight modes in the example. The ViewPager is used with the associated adapter (ScreenSlidePagerAdapter).
You can see the app in the Play Store to see the slider (search "Flight Recorder 24").
// In the main fragment java code
private View headerView;
private ViewPager mPager;
public ScreenSlidePagerAdapter mPagerAdapter;
// ...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View mainView = inflater.inflate(R.layout.monitoring_fragment,container, false);
// The header of the list
View view = inflater.inflate(R.layout.header_monitoring_fragment, mListView, false);
headerView = view;
//...
mPager = (ViewPager) view.findViewById(R.id.pager);
FragmentManager fm = getChildFragmentManager();
mPagerAdapter = new ScreenSlidePagerAdapter(fm);
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(UserConfiguration.getUserConf().getPositionFromFlightMode());
// Attach the page change listener inside the activity
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position)
{
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
UserConfiguration.getUserConf().setFlightMode(flight_mode);
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state)
{
// Code goes here
}
});
// ...
}
// ...
// Slider adapter
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// position to flight mode
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
FlightModeFragment flightModeFragment = FlightModeFragment.newInstance(flight_mode);
return flightModeFragment;
}
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
#Override
public int getCount()
{
return 4;
}
}
Then you have to create a Fragment with your slider content (here the class FlightModeFragment), it will be instanciated with an integer to identify the page embedded into a Bundle savedInstanceState (I have 4 pages).
public class FlightModeFragment extends Fragment
{
LinearLayout mainLayout;
ImageView live15minImageView;
ImageView modeImageView;
ImageView imageViewLeft;
ImageView imageViewRight;
private TextView textViewRecord;
private TextView textViewGps;
int flight_mode = UserConfiguration.AC_LISTENER_TRAVEL_RECORDER_MODE;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// handle fragment arguments
Bundle arguments = getArguments();
if(arguments != null)
{
flight_mode = arguments.getInt("flight_mode");
}
}
// ...
}

Navigating between Fragments while using a ViewPager

I've looked at so many questions here that I don't even know exactly what I'm looking for.
I have a simple app that uses a ViewPager. It has 3 tabs and there is a fragment for each tab. The first fragment contains a ListView. I want to be able to click on an element in the ListView and have that bring me to a different fragment.
So basically I want to remove the fragment that contained the ListView once an element is clicked and add in a new fragment. I've tried to do this in a few different ways with none working.
The last thing I tried was to edit the TabsPageAdapter once an element was clicked which pretty much works except when I press the back button it exits the app. Also it doesn't seem like the cleanest way of doing this.
TabsPagerAdapter
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
SherlockFragment mf;
TalkingPointsFragment tpf;
ContactFragment gf;
int mode = 0;
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
mf = new CanvassFragment();
tpf = new TalkingPointsFragment();
gf = new ContactFragment();
}
public TabsPagerAdapter(FragmentManager fm, int mode)
{
super(fm);
if(mode == 0)
{
mf = new CanvassFragment();
tpf = new TalkingPointsFragment();
gf = new ContactFragment();
}
else if(mode == 1)
{
mf = new ContactFragment();
tpf = new TalkingPointsFragment();
gf = new ContactFragment();
}
}
#Override
public SherlockFragment getItem(int index) {
switch (index) {
case 0:
return mf;
case 1:
return tpf;
case 2:
return gf;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
}
}
The onclick code:
ViewPager viewp = (ViewPager) getActivity().findViewById(R.id.pager);
TabsPagerAdapter mAdapter = new TabsPagerAdapter(getActivity().getSupportFragmentManager(),1);
viewp.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
layout_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:actionBarTabStyle="#drawable/actionbar_tab_indicator">
I FragmentStatePagerAdapter too and when a user selects map from the ActionBar, I add the GoogleMapsFragment on top of the FragmentStatePagerAdapter:
// create a new map
mapsFragment = GoogleMapFragment.newInstance();
// Then we add it using a FragmentTransaction.
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.add(android.R.id.content, mapsFragment,
FRAGMENT_MAP_TAG);
fragmentTransaction.commit();
For your case you would probably need to add it to the backstack too, which I have not because in my app the user has to navigate back using the ActionBar.
Thought this approach could work for you too when a user selects an item from your list.
Of course this has the disadvantage of not being able to use the FragmentStatePagerAdapter until the user navigates back. So I am not sure wether that would be acceptable for your app.
Ok, so this took a bit more code that I imagined. Hope you get the idea:
public class MainClass extends FragmentActivity implements CanvassCallback {
// save a single reference to ViewPager and TabsPagerAdapter
private ViewPager mViewPager;
private TabsPagerAdapter mAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mViewPager = (ViewPager) findViewById(R.id.pager);
this.mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), this);
mViewPager.setAdapter(mAdapter);
...
}
// from the CanvassCallback interface
public void itemSelected() {
mAdapter.canvassSelected();
mAdapter.notifyDataSetChanged();
}
#Override
public void onBackPressed() {
if (mViewPager.getCurrentItem() == 0 && mAdapter.isCanvassSelected() {
mAdapter.canvassSelected();
mAdapter.notifyDataSetChanged();
}
else {
super.onBackPressed();
}
}
}
Mockup of your CanvassFragment showing the callback
public class CanvassFragment extends SherlockFragment {
public interface CanvassCallback {
public void itemSelected();
}
private CanvassCallback canvassCallback;
public void setCanvassCallback(CanvassCallback canvassCallback) {
this.canvassCallback = canvassCallback;
}
...
// The onClick of your item
private void onClick() {
// notify your activity that an item was selected
canvassCallback.itemSelected();
}
}
The registeredFragments are not strictly needed but I think it provides some value if your need to call methoods on your Fragment from activity.
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
// see upvoted answer from http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private boolean canvassSelected = false;
private CanvassCallback canvassCallback;
public TabsPagerAdapter(FragmentManager fm, CanvassCallback canvassCallback) {
super(fm);
this.canvassCallback = canvassCallback;
}
public void canvassSelected() {
canvassSelected = !canvassSelected;
}
public boolean isCanvassSelected() {
return canvassSelected;
}
#Override
public SherlockFragment getItem(int index) {
switch (index) {
case 0:
if (canvassSelected)
return new ContactFragment();
CanvassFragment canvassFragment = new CanvassFragment();
// this ensures that your Activity gets notified when an item is clicked
canvassFragment.setCanvassCallback(canvassCallback);
return canvassFragment;
case 1:
return new TalkingPointsFragment();
case 2:
return new ContactFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Log.d(TAG, "instantiateItem " + position);
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.d(TAG, "destroyItem " + position);
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
}

Categories

Resources