Search code examples
androidandroid-fragmentsactionbarsherlockandroid-viewpagerandroid-fragmentactivity

Don't understand viewpager life cycle with fragment


I'm little bit dissapointed by the viewpager with fragments, since 4 days i try many solutions, without sucess.

I 'm beginner in fragments, i follow a great tutorial to create my viewpager. I can rotate phone no problem with fragments. But i must open a new activity from a fragment within viewpager and then go back on host activity which contain viewpager. In this point i can't get my fragment from host activity when i go back fron activity B. I don't understand what can i do ?

Exemple :

TabSessionActivity --> Fragment A --> Activity B --> TabsessionActivity(fragment A =NULL)

TabSessionActivity --> Fragment A -->Rotate phone --> TabsessionActivity(fragment A OK!)

Here My adapter :

public class MyPagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> fragments;
    private FragmentManager mFragmentManager; 

    // On fournit à l'adapter la liste des fragments à afficher
    public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        mFragmentManager=fm;

        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        for(Fragment mfragment:fragments){
            Log.i("Fragment Tag and Id"," FragmentTag:"+mfragment.getTag()+" FragmentID:"+mfragment.getId()+"NB fragments:"+this.fragments.size());

        }
        return this.fragments.get(position);

    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }





    public Fragment getActiveFragment(ViewPager container, int position) {
        String name = makeFragmentName(container.getId(), position);
        for(Fragment mfragment:mFragmentManager.getFragments()){
            Log.i("Fragment Tag and Id"," FragmentTag:"+mfragment.getTag()+" FragmentID:"+mfragment.getId()+" NB fragments:"+this.mFragmentManager.getFragments().size());
        }
        return  mFragmentManager.findFragmentByTag(name);

        }

        private static String makeFragmentName(int viewId, int index) {
            return "android:switcher:" + viewId + ":" + index;
        }
}

Then My Host activity :

public class TabsSessionActivity extends SherlockFragmentActivity {
    private GeoLocatingService mGeoService;
    private MyPagerAdapter mPagerAdapter;  
    private  ViewPager mViewPager;
//  private MyFragmentPagerAdapter mMyFragmentPagerAdapter;
    private Dashboard_Fragment fragment1;
    private OsmMapFragment fragment2;
    private Fragment1 fragment3;

    final IGeoLocatingServiceListener servicelistener = new IGeoLocatingServiceListener() {
        @Override
        public void dataChanged(final Object data) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i("TabSessionActivity:GeoService","Service rafraichi");
                    refreshCurrentFragment();

                }
            });
        }
    };

    /************************** SERVICE CONNECTION **********************/
    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("GeoService", "TabsSessionActivity:Disconnected!");
            mGeoService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            Log.i("TabSessionActivity:GeoService", "TabsSessionActivity:Connected!");
            mGeoService = ((GeoLocatingService.LocalBinder) service).getService();
            mGeoService.addListener(servicelistener);
            Log.i("TabSessionActivity:GeoService","Service connecté");
            refreshCurrentFragment();





        }
    };

    public GeoLocatingService getGeoLocatingService() {
        return mGeoService;
    }




    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set the view from main_fragment.xml
        setContentView(R.layout.activity_tabs_session);

        // Création de la liste de Fragments que fera défiler le PagerAdapter
        List fragments = new Vector();

        // Ajout des Fragments dans la liste
        fragments.add(Fragment.instantiate(this,OsmMapFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,Dashboard_Fragment.class.getName()));
        fragments.add(Fragment.instantiate(this,Fragment1.class.getName()));

        // Création de l'adapter qui s'occupera de l'affichage de la liste de
        // Fragments
        this.mPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(),fragments);



        // Affectation de l'adapter au ViewPager
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(this.mPagerAdapter);

      //Bind the title indicator to the adapter
        LinePageIndicator LineIndicator = (LinePageIndicator)findViewById(R.id.indicator);
        LineIndicator.setViewPager(mViewPager);


        //Style Line Indicator
        final float density = getResources().getDisplayMetrics().density;
        LineIndicator.setSelectedColor(0xFF45A5D7);
        LineIndicator.setUnselectedColor(0xFF888888);
        LineIndicator.setStrokeWidth(4 * density);
        LineIndicator.setLineWidth(30 * density);

        mViewPager.setCurrentItem(1);
        Log.i("TabSessionActivity:GeoService","On Create");


    }

    public void refreshCurrentFragment(){
        //Retrieve fragments instances


        fragment1 = (Dashboard_Fragment) this.mPagerAdapter.getActiveFragment(mViewPager, 1);
        fragment2 = (OsmMapFragment) this.mPagerAdapter.getActiveFragment(mViewPager, 0);
        fragment3 = (Fragment1)this.mPagerAdapter.getActiveFragment(mViewPager, 2);

        //Check if fragment is active and visible
        if (fragment1!=null){
            Log.i("TabSessionActivity:GeoService","Fragment trouvé");
            fragment1.onDatachangedCallback();
        }
        if (fragment2!=null){
            fragment2.onDatachangedCallback();
        }
        if (fragment3!=null){
            fragment3.onDatachangedCallback();
        }

    }



    @Override
    public void onStart() {
        super.onStart();
        //On attache la vue au service
        bindService(
                new Intent(this, GeoLocatingService.class),
                connection, BIND_AUTO_CREATE);
        Log.i("TabSessionActivity:GeoService","On start bind");
    }



    @Override
    public void onResume() {
        super.onResume();
            if(mGeoService!=null){
                Log.i("TabSessionActivity:GeoService","RefreshCurrentFragment()");
            }

    }

    @Override
    public void onPause() {
        super.onPause();
            if(mGeoService!=null){
                unbindService(connection);
                mGeoService.removeListener(servicelistener);
                mGeoService=null;
                Log.i("TabSessionActivity:GeoService","On pause unbind");
            }


    }

    @Override
    public void onDestroy() {
         if(mGeoService!=null){
                unbindService(connection);
                Log.i("TabSessionActivity:GeoService","On destroy unbind");
            }
        /*if(ServiceTools.isGeoLocatingServiceRunning(this)){
            stopService(new Intent(this, GeoLocatingService.class));
        }*/

        super.onDestroy();
    }



    @Override
    public boolean onKeyDown(int keycode, KeyEvent event) {
        if (keycode == KeyEvent.KEYCODE_BACK) {
            if(mGeoService!=null){
                if(mGeoService.getRecord()){
                showCancelRecordAlertToUser();
                }else{
                    startActivity(new Intent(this, MainActivity.class));
                    finish();
                }

            }else{
                startActivity(new Intent(this, MainActivity.class));
                finish();
            }

        }
        return super.onKeyDown(keycode, event);
    }

Log Cat says null for fragments when i go back on the host activity from activity B :

fragment1 = (Dashboard_Fragment) this.mPagerAdapter.getActiveFragment(mViewPager, 1);
            fragment2 = (OsmMapFragment) this.mPagerAdapter.getActiveFragment(mViewPager, 0);
            fragment3 = (Fragment1)this.mPagerAdapter.getActiveFragment(mViewPager, 2);

Solution

  • Try this:

    onUserInteraction(){
        super.onUserInteraction();
        switch (mViewPager.getCurrentItem()) {
        case 3:
            Fragment currentFragment = this.getSupportFragmentManager()
                    `.findFragmentByTag(getFragmentTag(mViewPager.getCurrentItem()));
            break;
       }
    
    private String getFragmentTag(int pos) {
        return "android:switcher:" + R.id.viewpager + ":" + pos;
    }
    

    Log currentFragment value and check whether it is NULL. This worked for me.