How to determine when clips are visible in ViewPager

Problem: ViewPager fragment onResume() was triggered before the fragment was actually visible.

For example, I have 2 with ViewPager and fragmentpager adapter. The second fragment is for authorized users only, and I need to have users log in when the fragment is visible (using the alert dialog box).

However, when the first clip is visible, ViewPager creates a second clip to cache the second clip and make it visible when the user starts sliding.

Therefore, the onResume() event is triggered in the second fragment before it is visible. That's why I try to find an event that fires when the second fragment becomes visible and displays a dialog when appropriate.

How can this be done?

#1 building

How to determine when clips are visible in ViewPager

You can override the following setUserVisibleHint in your Fragment:

public class MyFragment extends Fragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
        }
        else {
        }
    }
}

#2 building

This is another way to use onPageChangeListener:

  ViewPager pager = (ViewPager) findByViewId(R.id.viewpager);
  FragmentPagerAdapter adapter = new FragmentPageAdapter(getFragmentManager);
  pager.setAdapter(adapter);
  pager.setOnPageChangeListener(new OnPageChangeListener() {

  public void onPageSelected(int pageNumber) {
    // Just define a callback method in your fragment and call it like this! 
    adapter.getItem(pageNumber).imVisible();

  }

  public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

  }

  public void onPageScrollStateChanged(int arg0) {
    // TODO Auto-generated method stub

  }
});

#3 building

Rewrite for this purpose Fragment.onHiddenChanged() .

public void onHiddenChanged(boolean hidden)

When a clip is hidden (by isHidden() Called when it has been changed. The start of the clip is not hidden; this method is called whenever the clip changes state from that state.

parameter
hidden - boolean: true if the fragment is now hidden; false if it is not visible.

#4 building

Update: Android support library (rev 11) final Fixed user visible prompt issues , now, if you use the support library for fragments, you can safely use getUserVisibleHint() or override setUserVisibleHint() to capture the changes described in Goren's answer.

Update 1 this is a small problem with getUserVisibleHint(). By default, this value is true.

// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;

Therefore, there may be a problem trying to use setUserVisibleHint() before calling it. As a workaround, you can set values in the onCreate method like this.

public void onCreate(@Nullable Bundle savedInstanceState) {
    setUserVisibleHint(false);

Outdated answers:

In most cases, the ViewPager displays only one page, but if you use the fragmentstatepager adapter in Android support library pre-R 11, the pre cached fragment is also placed in the visible state (actually invisible).

I cover:

public class MyFragment extends Fragment {
    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible) {
            // ...
        }
    }
   // ...
}

To capture the focus state of a clip, I think this is the most appropriate state for visibility, because only one clip in the ViewPager can actually place its menu item with the item of the parent activity.

#5 building

I override the Count method of the associated FragmentStatePagerAdapter and have it return the total Count minus the number of pages to hide:

 public class MyAdapter : Android.Support.V13.App.FragmentStatePagerAdapter
 {   
     private List<Fragment> _fragments;

     public int TrimmedPages { get; set; }

     public MyAdapter(Android.App.FragmentManager fm) : base(fm) { }

     public MyAdapter(Android.App.FragmentManager fm, List<Android.App.Fragment> fragments) : base(fm)
     {
         _fragments = fragments;

         TrimmedPages = 0;
     }

     public override int Count
     {
         //get { return _fragments.Count; }
         get { return _fragments.Count - TrimmedPages; }
     }
 }

Therefore, if you initially added three clips to the ViewPager, and only the first two clips are displayed before certain conditions are met, override the number of pages by setting TrimmedPages to 1, and it should only display the first two pages.

This works well for the end page, but it doesn't really help the beginning or middle page (although there are many ways to do this).

Tags: Fragment Android

Posted on Tue, 07 Jan 2020 20:17:40 -0800 by SnakeO