ViewPager не загружает фрагменты вне экрана, когда 3 элемента видны пользователю - PullRequest
0 голосов
/ 13 марта 2019

Я использую FragmentStatePagerAdapter для отображения карусельного вида, где пользователю видны сразу 3 фрагмента.Таким образом, по определению ViewPager, в памяти не будет загружаться соседних фрагментов.Следовательно, имеется задержка в отображении фрагмента при прокрутке представления карусели.Поэтому я устанавливаю offScreenPageLimit равным 2. Но, тем не менее, я вижу, что соседние фрагменты не загружены в память и что задержка отображения данных.Я должен использовать FragmentStatePagerAdapter, так как список является динамическим и большим.Пожалуйста, помогите.

private CarouselViewPager _pager;
private DummyCarouselAdapter_adapter;

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var v = inflater.Inflate(Resource.Layout.FragmentDummyBaseScreen, container, false);
        _pager = v.FindViewById<CarouselViewPager>(Resource.Id.viewpagerDummy);

        InitBaseViews(v);
        _list = new List<DummyCarouselItem>();

        var dm = new DisplayMetrics();
        Activity.WindowManager.DefaultDisplay.GetMetrics(dm);
        _pager.OffscreenPageLimit = 2;
        _pager.SetNoOfVisibleItems(3,
            "Tv".Equals(dm.DensityDpi.ToString()) ? PagerItemPaddingTvdpi : PagerItemPaddingHdpi);
        Activity.WindowManager.DefaultDisplay.GetMetrics(dm);
        _dataProvider = new FavoriteDateProvider(Activity);
        _adapter = new DummyCarouselAdapter(Activity, ChildFragmentManager, _list,
            dm.HeightPixels / 3, dm.HeightPixels / 3);
        _pager.Adapter = _adapter;
        _callListWorkerThread = new Thread(RetrieveFavList);
        _callListWorkerThread.Start();


        Activity.SupportFragmentManager.AddOnBackStackChangedListener(this);
        return v;
    }

DummyCarousalAdapter.cs

namespace HMI_Common.Adapters.Dummy
{
class DummyCarouselAdapter: FragmentStatePagerAdapter, ViewPager.IOnPageChangeListener
{
    private List<DummyCarouselItem> _list;

    public int ActivePosition { get; set; }

    private int _previousPage;

    public float BigScale = 1.0f;
    public float SmallScale = 0.5f;
    private readonly int _itemWidth;
    private readonly int _itemHeight;
    public bool _animate;
    private Context _context;


    private SparseArray<WeakReference<Fragment>> mFragments = new SparseArray<WeakReference<Fragment>>();

    public DummyCarouselAdapter(Context context, Android.Support.V4.App.FragmentManager fm, List<DummyCarouselItem> list, int itemWidth, int itemHeight) :
        base(fm)
    {
        _list = list;
        _context = context;
        ActivePosition = 1;
        _itemWidth = itemWidth;
        _itemHeight = itemHeight;
    }

    private void ApplyScaleAnimation(int position)
    {
        var currFrag = (DummyPagerItemFragment)GetFragment(position);
        var prevFrag = (DummyPagerItemFragment)GetFragment(_previousPage);

        if (_animate)
        {
            StartScaleAnimation(currFrag, true, true);
            StartScaleAnimation(prevFrag, false, true);
        }

        else
        {
            StartScaleAnimation(currFrag, true, false);
            StartScaleAnimation(prevFrag, false, false);
            _animate = true;
        }
    }


    private void StartScaleAnimation(DummyPagerItemFragment fragment, bool scaleUp, bool animate)
    {
        if (fragment == null)
        {
            return;
        }

        DummyCarouselRelativeLayout cur = GetRootView(fragment);
        cur.StartScaleAnimation(scaleUp, animate);
    }

    private DummyCarouselRelativeLayout GetRootView(Fragment f)
    {
        return (DummyCarouselRelativeLayout)f
            .View.FindViewById(Resource.Id.root_container);
    }

    public override int Count => _list.Count;

    public override Fragment GetItem(int position)
    {
        var isActive = position == ActivePosition;
        var scale = isActive ? BigScale : SmallScale;
        var item = _list[position];
        var pos = position;
        return DummyPagerItemFragment.NewInstance(item, pos, isActive, scale, _itemWidth, _itemHeight, _list.Count);
    }

    public override Object InstantiateItem(ViewGroup container, int position)
    {
        var f = (Fragment)base.InstantiateItem(container, position);
        mFragments.Put(position, new WeakReference<Fragment>(f));
        return f;
    }

    public Fragment GetFragment(int position)
    {
        Fragment f;
        var frag = mFragments.Get(position);
        if (frag != null)
        {
            frag.TryGetTarget(out f);
        }
        else
        {
            f = null;
        }

        return f;
    }

    public override void DestroyItem(ViewGroup container, int position, Object @object)
    {
        base.DestroyItem(container, position, @object);
        mFragments.Remove(position);
    }

    public void OnPageScrollStateChanged(int state)
    {

    }

    public void UpdateFragmentList(List<DummyCarouselItem> list, int activePosition, bool animate = true)
    {
        if (list == null) return;
        _animate = animate;

        ((Activity) _context).RunOnUiThread(() =>
        {
            ActivePosition = activePosition;
            _previousPage = ActivePosition - 1;
            _list = null;
            _list = new List<DummyCarouselItem>(list);
            NotifyDataSetChanged();
        });
    }

    public override int GetItemPosition(Object @object)
    {
        return PositionNone;
    }

    public void OnPageScrolled(int position, float positionOffset, int positionOffsetPixels)
    {
        try
        {
            if (positionOffset >= 0f && positionOffset <= 1f)
            {
                if (positionOffset > 0.5 && _previousPage != position + 1)
                {
                    ActivePosition = position + 1;
                    UpdateFragmentState(position + 1);
                    ApplyScaleAnimation(position + 1);
                    _previousPage = position + 1;
                }
                else if (positionOffset < 0.5 && _previousPage != position)
                {
                    ActivePosition = position;
                    UpdateFragmentState(position);
                    ApplyScaleAnimation(position);
                    _previousPage = position;
                }
            }
        }
        catch (Exception e)
        {
            Log.Debug(TAG, "Exception: " + e.Message);
        }
    }

    public void OnPageSelected(int position)
    {

    }

    private void UpdateFragmentState(int position)
    {
        var prevFrag = (DummyPagerItemFragment)GetFragment(position - 1);
        var currFrag = (DummyPagerItemFragment)GetFragment(position);
        var nextFrag = (DummyPagerItemFragment)GetFragment(position + 1);

        prevFrag?.SetActive(false);
        currFrag?.SetActive(true);
        nextFrag?.SetActive(false);
    }
}
}
...