Android 当滚动和重新加载同时发生时,RecyclerView崩溃
在我的应用程序中,我使用了一个Android 当滚动和重新加载同时发生时,RecyclerView崩溃,android,xamarin,android-recyclerview,xamarin.android,Android,Xamarin,Android Recyclerview,Xamarin.android,在我的应用程序中,我使用了一个RecyclerView,当用户向下滚动时,它应该会继续加载图像。但这让我想到了一个我无法解决的问题。基本上,我是说 loadPhotos.LoadMoreItems(3); 也就是说,首先加载3张照片。 一旦达到某一点(通过滚动),继续加载另外3张图片(组成一行): 如果我只加载3张照片,首先,手机会加载3张照片,一秒钟后,手机会加载下一行,因为位置已到达。所以这确实有效,但如果我开始滚动,我会得到以下错误: “cannot call this
RecyclerView
,当用户向下滚动时,它应该会继续加载图像。但这让我想到了一个我无法解决的问题。基本上,我是说
loadPhotos.LoadMoreItems(3);
也就是说,首先加载3张照片。
一旦达到某一点(通过滚动),继续加载另外3张图片(组成一行):
如果我只加载3张照片,首先,手机会加载3张照片,一秒钟后,手机会加载下一行,因为位置已到达。所以这确实有效,但如果我开始滚动,我会得到以下错误:
“cannot call this method while RecyclerView is computing a layout or scrolling”
在这一行:
mAdapter.NotifyItemRangeChanged(oldCount - 1, loadPhotos.pictures.Count);
另一个有趣的事实是,我可以在小型手机上实现这一点,但屏幕更大的手机(三星s8)会更快崩溃
所以,我真的很困惑如何做到这一切。作为额外信息,这是我的全部活动:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Fragment_Gallery);
galleryType = Intent.GetIntExtra("galleryType", 0);
picturesinarow = Intent.GetIntExtra("picturesinarow", 1);
recyclerLayout = Intent.GetIntExtra("recyclerLaoyut", (int)RecyclerLayout.Multiplepics);
hasHeader = Intent.GetBooleanExtra("hasHeader", false);
// Instantiate the photo album:
loadPhotos = new BookOfLife.CustomRecyclerView.ReloadAdapter(this.galleryType);
loadPhotos.LoadMoreItems(3);//(Constants.ITEMSPERPAGE);
// Get our RecyclerView layout:
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
//............................................................
// Layout Manager Setup:
// Use the built-in linear layout manager:
//mLayoutManager = new LinearLayoutManager(this);
// Or use the built-in grid layout manager (two horizontal rows):
mLayoutManager = new GridLayoutManager(this, this.picturesinarow, GridLayoutManager.Vertical, false);
// Plug the layout manager into the RecyclerView:
mRecyclerView.SetLayoutManager(mLayoutManager);
//............................................................
// Adapter Setup:
// Create an adapter for the RecyclerView, and pass it the
// data set (the photo album) to manage:
mAdapter = new PhotoAlbumAdapter(loadPhotos, this.picturesinarow, (RecyclerLayout)this.recyclerLayout, this.hasHeader);
// Register the item click handler (below) with the adapter:
mAdapter.ItemClick += OnItemClick;
// Plug the adapter into the RecyclerView:
mRecyclerView.SetAdapter(mAdapter);
//.........................................................................
//Set Spanwidth for GridHeader
mLayoutManager.SetSpanSizeLookup(new GridViewSpansizeLookup(mAdapter, mLayoutManager));
// On Scroll Listener
var onScrollListener = new XamarinRecyclerViewOnScrollListener(mLayoutManager);
onScrollListener.LoadMoreEvent += (object sender, EventArgs e) =>
{
int oldCount = loadPhotos.pictures.Count;
loadPhotos.LoadMoreItems(3);//(Constants.LOADNEXTITEMSTHRESHHOLD);
mAdapter.NotifyItemRangeChanged(oldCount - 1, loadPhotos.pictures.Count);
};
mRecyclerView.AddOnScrollListener(onScrollListener);
}
protectedoverride void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Fragment_Gallery);
galleryType=Intent.GetIntExtra(“galleryType”,0);
picturesinarow=Intent.GetIntExtra(“picturesinarow”,1);
recyclerLayout=Intent.GetIntExtra(“recyclerLaoyut”,(int)recyclerLayout.Multiplepics);
hasHeader=Intent.GetBooleanExtra(“hasHeader”,false);
//实例化相册:
loadPhotos=newbookoflife.customrecyclererview.reloadapter(this.galleryType);
loadPhotos.loadmoreims(3);/(Constants.ITEMSPERPAGE);
//获取我们的RecyclerView布局:
mRecyclerView=findviewbyd(Resource.Id.recyclerView);
//............................................................
//布局管理器设置:
//使用内置的线性布局管理器:
//mLayoutManager=新的LinearLayoutManager(此);
//或使用内置的栅格布局管理器(两个水平行):
mLayoutManager=新建GridLayoutManager(this,this.picturesinarow,GridLayoutManager.Vertical,false);
//将布局管理器插入RecyclerView:
mRecyclerView.SetLayoutManager(mllayoutmanager);
//............................................................
//适配器设置:
//为RecyclerView创建适配器,并将
//要管理的数据集(相册):
mAdapter=新相册适配器(loadPhotos,this.picturesinarow,(RecyclerLayout)this.RecyclerLayout,this.hasHeader);
//向适配器注册项目单击处理程序(如下所示):
mAdapter.ItemClick+=OnItemClick;
//将适配器插入RecyclerView:
mRecyclerView.SetAdapter(mAdapter);
//.........................................................................
//设置GridHeader的宽度
设置PansizeLookup(新的GridViewSpansizeLookup(mAdapter,mLayoutManager));
//滚动侦听器
var onScrollListener=新的XamarinRecycleServiceOnScrollListener(mLayoutManager);
onScrollListener.LoadMoreEvent+=(对象发送方,事件参数e)=>
{
int oldCount=loadPhotos.pictures.Count;
loadPhotos.LoadMoreItems(3);/(Constants.loadnextitemsthreshold);
NotifyItemRangeChanged(oldCount-1,loadPhotos.pictures.Count);
};
mRecyclerView.AddOnScrollListener(onScrollListener);
}
希望你们能帮我:)好的,我似乎找到了一个简单的解决方法:
if (!mRecyclerView.isComputingLayout())
mAdapter.NotifyItemRangeChanged(oldCount - 1, loadPhotos.pictures.Count);
我只需要确保,我总是有足够的照片,以便“回收者”视图可以滚动。您正在同步加载图像,这就是为什么屏幕较小的手机能够显示您的内容,但在屏幕较大的手机上,您的代码被调用的时间远远早于它能够读取以前的图像。您可以使用BlockingCollection异步加载图像,然后显示它们。生产者/消费者模式。好的,听起来很合理。但是我真的不知道如何在我的问题收集中使用它。研究生产者/消费者模式。这似乎是你问题的确切答案。谢谢!不过我现在确实找到了另一个简单的方法:)好。您还可以在加载照片时预加载下一批照片。
if (!mRecyclerView.isComputingLayout())
mAdapter.NotifyItemRangeChanged(oldCount - 1, loadPhotos.pictures.Count);