Check if fragment is currently visible or no

前端 未结 10 801
悲&欢浪女
悲&欢浪女 2020-12-05 03:10

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:

<
相关标签:
10条回答
  • 2020-12-05 03:35
    public static boolean isFragmentVisible(Fragment fragment) {
        Activity activity = fragment.getActivity();
        View focusedView = fragment.getView().findFocus();
        return activity != null
                && focusedView != null
                && focusedView == activity.getWindow().getDecorView().findFocus();
    }
    

    original post

    0 讨论(0)
  • 2020-12-05 03:38

    When I had a similar problem I solved it by using this hacky method 'going under the hood' like

    Inside your FragmentPagerAdapter(s) add this function.

    public Fragment getActiveFragment(ViewPager container, int position) {
            String name = makeFragmentName(container.getId(), position);
            return fm.findFragmentByTag(name);
        }
    
        private static String makeFragmentName(int viewId, int index) {
            return "android:switcher:" + viewId + ":" + index;
        }
    

    It is not the most graceful solution but as long as it works

    CAUTION

    This is a private method internal to ViewPager that could change at any time or for any OS version.

    0 讨论(0)
  • 2020-12-05 03:42

    try this

    @Override
        public void setMenuVisibility(final boolean visible) {
            super.setMenuVisibility(visible);
            if (visible) {
    
            }
            else
            {       
    
            }
        }
    
    0 讨论(0)
  • 2020-12-05 03:42

    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) {
    
            }
        });
    
    0 讨论(0)
  • 2020-12-05 03:43

    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.

    0 讨论(0)
  • 2020-12-05 03:43

    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.

    0 讨论(0)
提交回复
热议问题