Check if fragment is currently visible or no

28,822

Solution 1

You can check, whether the View that fragment inflated is visible on the device's screen:


    Fragment fragment = ... // retrieve from `ViewPager`'s adapter.
    View fragmentRootView = fragment.getView();
    if (fragmentRootView != null && fragmentRootView.getGlobalVisibleRect(new Rect())) {
        // fragment is visible
    } else {
        // fragment is not visible
    }

getGlobalVisibleRect() will return true if part of the view is visible at the root level.

Solution 2

try this

@Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible) {

        }
        else
        {       

        }
    }

Solution 3

You can override setUserVisibleHint() in each fragment where you want to check whether it is visible or not with a additional flag. For an example

Java:

boolean isVisited = false;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) 
{
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser && !isVisited ) 
    {
         isVisited = true;
    }
    else if(isVisited)
    {
        // this fragment is already in front of user
    }
}

I was having similar problem. Once I was need to load data from server to fragment only when it was in-front of user. I solved it as above.

Kotlin :

    private var isVisited: Boolean = false


    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser && !isVisited!! )
        {
            isVisited = true;
        }
        else if(isVisited!!)
        {
            Toast.makeText(activity!!, "Location required", Toast.LENGTH_SHORT).show()
        }
    }

Hope it will help you as well.

Solution 4

Give this a try..

The isVisible() adds an extra layer of visibility check.

    ViewPager viewPager=(ViewPager)findViewById(R.id.view_pager); 

    final Fragment[] fragments={new DFragment(),new MyFragment()};  //add all the other fragment objects present in the view pager......

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if(fragments[position].isVisible()){
                //Cool stuff to do.
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

Solution 5

As far as I have tried I think this will work Please try and let me know. Do something like this in your activity.


public boolean isFragmentVisible(SwipeAdapter swipeAdapter) {
        SwipeAdapter swipeAdapterA = fragmentA.getViewPagerAdapter();
        BFragment bFragment = (BFragment) swipeAdapterA.getFragment(0);
        if (bFragment != null) {
            SwipeAdapter swipeAdapterB = bFragment.getViewPagerAdapter();
            CFragment cFragment = (CFragment) swipeAdapterA.getFragment(0);
            if (cFragment != null) {
                SwipeAdapter swipeAdapterC = cFragment.getViewPagerAdapter();
                DFragment dFragment = (DFragment) swipeAdapterA.getFragment(0);
                if (dFragment != null) {
                    return dFragment.isFragmentVisible();
                }
            }
        }
        return false;
    }

Use this class as your viewpager adapter

  class SwipeAdapter extends FragmentPagerAdapter {
        private Map<Integer, String> mFragmentTags;
        private FragmentManager mFragmentManager;

        private String mPagetile[];

        public SwipeAdapter(FragmentManager fm, Context context) {
            super(fm);
            mPagetile = context.getResources().getStringArray(R.array.pageTitle);
            mFragmentManager = fm;
            mFragmentTags = new HashMap<>();
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new "Your_fragment";
                default:
                    break;
            }
            return null;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Object obj = super.instantiateItem(container, position);
            if (obj instanceof Fragment) {
                Fragment f = (Fragment) obj;
                String tag = f.getTag();
                mFragmentTags.put(position, tag);
            }
            return obj;
        }

        public Fragment getFragment(int position) {
            String tag = mFragmentTags.get(position);
            if (tag == null)
                return null;
            return mFragmentManager.findFragmentByTag(tag);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mPagetile[position];
        }

        @Override
        public int getCount() {
            return "Number of fragments";
        }
    }

Now in your DFragment do this

 boolean isVisible=false;

        @Override
        public void setMenuVisibility(boolean menuVisible) {
            super.setMenuVisibility(menuVisible);
            isVisible=menuVisible;
        }

        public boolean isFragmentVisible(){
            return isVisible;
        }

Let me know if it worked if not let me know the reason.

Share:
28,822
Vikash Parajuli
Author by

Vikash Parajuli

Contact: [email protected]

Updated on April 04, 2020

Comments

  • Vikash Parajuli
    Vikash Parajuli about 4 years

    I know there are lots of similar questions in StackOverflow but my question is little different.

    I have nested hierarchy of Fragments like in below structure:

                                      Activity
                                         |
                                         |
                                     AFragment
                                         |
                                    (ViewPager)
                                     |       |         
                                     |       |         
                             BFragment       BFragment  .....
                                |                       
                           (ViewPager)                       
                            |       |                         
                            |       |                         
                     CFragment     CFragment  ...
                         |
                    (ViewPager)                       
                      |     |                              
                      |     |                        
               DFragment   DFragment ...
    

    Now i want to know that whether DFragment is showing to user or not?

    I tried lots of solution from StackOverflow but couldn't get sucess.

    What i tried is:

    I tried setUserVisibleHint() but it returns truefor multiple DFragment in above hierarchy which is a cause of ViewPager

    I also tried from these links: link1, link2, link3 and so on... but did not got actual solution.

    Waiting for help. Thank you.

    UPDATE

    Adapter Class

    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);
            }
        }