ViewPager Current Fragment Visibility

2019-06-09 08:54发布

问题:

What I Have

I have a ViewPager with 5 fragments. I want to animate some TextViews inside the fragments whenever they become visible to the user.

I can't use onResume() as the fragments to the left and right are already created. I can't use setUserVisibilityHint() as it is called before onCreateView() so the views are not ready yet.

So what should be the way to animate the views whenever a particular fragment becomes visible to the user?

回答1:

I'm not sure, but if you say that setUserVisibilityHint calls before onCreateView, than check view on null here (make reference on view - field), and if it not null - animate it. Also animate it always in onCreateView.



回答2:

(1) I can't use onResume() as the fragments to the left and right are already created. (2) I can't use setUserVisibilityHint() as it is called before onCreateView() so the views are not ready yet.

So what should be the way to animate the views whenever a particular fragment becomes visible to the user?

You're right on (1) and (2). However, setUserVisibilityHint() gets called Once Again with a True value after the Fragment comes to Front on Display. But on First Run the Fragment to be shown gets its setUserVisibilityHint() called before onCreateView().

SOL: You should use the above said behaviour of setUserVisibilityHint() along with onResume() to animate the views whenever a particular fragment becomes visible to the user.

  • Scenario 1: On First Run: Displayed Fragment's setUserVisibilityHint(boolean isVisibleToUser) gets called with True param value. But as the Fragment's State is not Resumed we postpone and let the onResume() handle animation.
  • Scenario 2: For Other Fragments that are already in Resume State, setUserVisibilityHint(boolean isVisibleToUser) will get called with True param it they come on to Display. Here you check for the Fragment Animated or not and Do animation.

CODE

a) Declare two Global Boolean Fields: isAnimated and isOnDisplay

a.1) Set isAnimated boolean to True;

b) Override setUserVisibilityHint(boolean isVisibleToUser):

Here you set isOnDisplay boolean to isVisibleToUser and check is the Fragment Not Already Animated and is in Resumed State and is Visible to User.

{ if(!isAnimated && isResumed() && isVisibleToUser) // DO Animation }

c) Override onResume()

Check if the Fragment Not Already Animated and is Visible to User.

{ if(!isAnimated && isVisibleToUser) // DO Animation }


回答3:

I know this answer might be a bit late, but I hope it can help others in a similar situation.

You could use FragmentViewPager library (I am the author), which deals with the issue you are facing for you. Its features are:

  • allows its Fragment pages to get notified when they are actually visible/invisible to the user
  • supports multiple levels of FragmentViewPagers (nesting)
  • provides methods to control its paging

A basic usage would be:

  1. Attach FragmentViewPager programmatically or via XML to an Activity or Fragment, as you would with native ViewPager
  2. Set FragmentViewPager's adapter. Your adapter should inherit com.sbrukhanda.fragmentviewpager.adapters.FragmentPagerAdapter or com.sbrukhanda.fragmentviewpager.adapters.FragmentStatePagerAdapter
  3. Override onResumeFragments() of the hosting Activity and call FragmentViewPager.notifyPagerVisible():

    private FragmentViewPager mFragmentsPager;
    
    @Override 
    public void onResumeFragments() {
        super.onResumeFragments();
        mFragmentsPager.notifyPagerVisible();
        ... 
    }
    

    or onResume() of the hosting Fragment and call FragmentViewPager.notifyPagerVisible():

    private FragmentViewPager mFragmentsPager;
    
    @Override 
    public void onResume() {
        super.onResume();
        mFragmentsPager.notifyPagerVisible();
        ... 
    }
    
  4. Override onPause() of the hosting Activity or Fragment and call FragmentViewPager.notifyPagerInvisible():

    private FragmentViewPager mFragmentsPager;
    
    @Override 
    public void onPause() {
        super.onPause();
        mFragmentsPager.notifyPagerInvisible();
        ... 
    }
    
  5. Implement FragmentVisibilityListener on all Fragment pages that you wish to receive callbacks for their visibility state
  6. You are ready to go!

If you wish to see a more complete sample code, then check project's sample project.



回答4:

If you want to do it in individual fragments, then you can use isVisible() for each fragment in your fragment transition and create a listener. Whenever a fragment will become visible , listener will be invoked and each fragment will implement that listener and do your intended task in the overridden method.