我正在使用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);
}
}
}