Android 如何使RecyclerView停止回收已定义的位置?
我的问题是:我有一个视频流发生在RecyclerView中的一个视图上 当用户滚动时,视图被回收,其他相机在回收的视图支架上开始自己的流。这对用户界面不利,因为流式处理需要几秒钟才能启动 我怎么能对RecyclerView说:“嘿,Recycler,拜托,不要回收那个确切的位置x,并且总是给那个位置一个你第一次给它的相同的视图持有者,而不是随机的”Android 如何使RecyclerView停止回收已定义的位置?,android,android-layout,android-recyclerview,android-viewholder,recycle,Android,Android Layout,Android Recyclerview,Android Viewholder,Recycle,我的问题是:我有一个视频流发生在RecyclerView中的一个视图上 当用户滚动时,视图被回收,其他相机在回收的视图支架上开始自己的流。这对用户界面不利,因为流式处理需要几秒钟才能启动 我怎么能对RecyclerView说:“嘿,Recycler,拜托,不要回收那个确切的位置x,并且总是给那个位置一个你第一次给它的相同的视图持有者,而不是随机的” 请有人帮助我=(如果您使用的是查询,您可以使用 query.limit(//no of items you want to show in your
请有人帮助我=(如果您使用的是查询,您可以使用
query.limit(//no of items you want to show in your RecyclerView)
试试看
或者请将查询代码张贴在ViewHolder
上,以便不回收
发件人:
通知回收者此项目是否可以回收。不可回收的视图将不会重新用于其他项目,直到稍后将setIsRecyclable()设置为true
这将导致仅创建一个ViewHolder
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
@Override
public void onViewAttachedToWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder) {
holder.setIsRecyclable(false);
}
super.onViewAttachedToWindow(holder);
}
@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder){
holder.setIsRecyclable(true);
}
super.onViewDetachedFromWindow(holder);
}
...
}
公共类MyAdapter扩展了RecyclerView.Adapter{
...
@凌驾
ViewAttachedTowindow上的公共无效(最终回收视图。ViewHolder){
if(视频视图支架的支架实例){
holder.setIsRecyclable(假);
}
super.onViewAttachedToWindow(持有人);
}
@凌驾
ViewDetachedFromWindow上的公共无效(final RecyclerView.ViewHolder){
if(视频视图支架的支架实例){
holder.setIsRecyclable(真);
}
super.onview从窗口分离(支架);
}
...
}
您的问题来自viewholder本身。viewholder保留对视图的引用,而适配器不保留。适配器仅保留数据收集。因此,向viewholder添加一个字段,以保留对用于在viewholder中填充视图的数据元素的引用。换句话说:
public class SomeViewHolder extends RecyclerView.ViewHolder{
private View view;
private Data data;
public SomeViewHolder(View itemView) {
super(itemView);
view = itemView;
}
public void bindData(Data data){
view.setData(data);
this.data = data;
}
public void setData(Data data){
this.data = data;
}
public Data getData(){
return data;
}
public View getView(){
return view;
}
}
现在,viewholder知道适配器的哪个元素正在使用。因此,在重写适配器中的绑定方法时,可以检查holder是否已与某些数据绑定,如果数据包含视频,则可以避免绑定并强制设置已加载的视图
@Override
public void onBindViewHolder(SomeViewHolder holder, int position) {
//videoViewData is a data field you have to put into the adapter.
//videoView is a view field you have to put into the adapter.
if(adapterData.get(position).equals(videoViewData)){
holder.setView(videoView);
holder.setData(adapterData.get(position));
}else{
holder.bindData(adapterData.get(position));
if(adapterData.get(position).isVideo()){
videoViewData = adapterData.get(position);
videoView = holder.getView();
}
}
}
最后,您必须重写适配器中的onViewRecycled方法,因此,当包含视频的视图被回收时,您可以获取该视图并将其放在其他地方
public void onViewRecycled(SomeViewHolder holder){
if(holder.getData().isVideo()){
videoViewData = holder.getData().
videoView = holder.getView();
videoView.pauseVideo();
}
}
请记住,如果您不管理存储的视图,这可能会导致一些严重的泄漏。此外,您必须定义告知数据何时为视频的方法,以及正确定义的等于方法。请尝试在特定位置使用此方法:
holder.setIsRecyclable(false);
希望这会有所帮助。在适配器的
getItemViewType(int position)
方法中,为每个视频指定唯一的值,这样它将始终为相同的视频返回相同的ViewHolder
- 为每种视频类型返回唯一的正数作为类型(这里我使用适配器位置作为唯一键)
- 对于任何非视频项目,返回负数。(这里没有什么特别的,只是为了避免与视频项目冲突,我们对非视频项目使用负数)
RecyclerView多次使用一个视图,当它包含一次未显示在屏幕上的列表时(意味着列表包含大量未同时显示在屏幕上的项目,您需要上下滚动)。当用户滚动列表时,屏幕外的项目被重新使用以显示剩余的列表项目,这称为回收 要停止回收项目,请在onBindViewHolder方法中调用此方法:
viewHolder.setIsRecyclable(false);
viewHolder.setIsRecyclable(true);
此语句停止了视图的循环使用
要开始回收项目,请在onBindViewHolder方法中调用此方法:
viewHolder.setIsRecyclable(false);
viewHolder.setIsRecyclable(true);
我希望这能解决你的问题。
谢谢在recyclerview中处理不可回收物品的最佳方法此答案将解决您的问题
查询?你是什么意思?你是如何把你的数据放在回收者的视野中的?请发布您的代码这是一个简单的iTen数组列表,每个项目都有一个布尔值,指示它是视频流还是简单的照片。layoutManager=new LinearLayoutManager(getApplicationContext(),//要显示的项目数);然后在适配器中返回//no of items you want show.size()。如果不想回收,也许可以使用
ScrollView
问题在于它是一个设备列表。很多设备没有这个问题,但其中一些设备是摄像头。我想通过用户在这些相机卡上按开始流媒体,但是当滚动的时候,视图会被回收。这是我不想要的东西,我试过了。但问题是:该视图不会为任何项目回收,即使是原始项目也是如此。。。因此,当回收者再次到达相机时,它将创建另一个视图。@DanielOliveira,从何处执行viewholder.setIsRecyclable(false)
?onBindViewHolder或onCreateViewHolder。这个方法做的正是它所做的:它不会回收视图,但会创建另一个viewholder,它仍然无法解决问题。谢谢你的努力,我尝试了你的代码,但在视频卡显示后,它仍然会提供不同的Holder。我正在使用viewholder的.hascode()方法检查它们是否不同=(它仍然提供不同的持有者
我已经检查过,onCreateViewHolder
只调用一次。方法很有趣,但仍然存在一个问题。如何“删除”这是一个巨大的解决方案,它向我们展示了RecyclerView的api中需要一些官方的东西来允许我们达到这种行为。但这确实有效,我给你我的奖励分数。谢谢Darish。很好的解决方案。@Darish关于我的观点有什么想法,我只是不希望第一项是recycled,我甚至可以完全不回收recyclerview。这是我的代码:实际上这并不能解决问题。Instea