我的问题是:我在RecyclerView内的其中一个视图上发生了视频流。
当用户滚动时,视图会被回收,其他摄像头会在该回收的视图符号上启动自己的流式传输。这对用户界面不利,因为流式处理需要几秒钟才能启动。
我怎么能对RecyclerView说:“嘿嘿回收器,请不要回收那个确切的位置 x 并给那个位置总是你给它的同一个看台第一次,而不是随机的“?
请有人帮助我=(
答案 0 :(得分:14)
在适配器的getItemViewType(int position)
方法中,为每个视频分配唯一值,因此它将始终为同一视频返回相同的ViewHolder。
我希望你明白这个主意。干杯:)
@Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
if(dataList.get(position).isVideo()){
return position;
}else{
return -1;//indicates general type, if you have more types other than video, you can use -1,-2,-3 and so on.
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case -1: View view1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.general_item, parent, false);
return new GeneralViewHolder(view1);
default:View view2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
return new VideoViewHolder(view2);
}
}
答案 1 :(得分:12)
对您希望不的ViewHolder
执行viewHolder.setIsRecyclable(false)
。
来自docs of ViewHolder#setIsRecyclable(boolean):
通知回收商是否可以回收此物品。在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);
}
...
}
答案 2 :(得分:2)
您的问题来自观看者本身。查看者保持对视图的引用,而适配器则不参考。适配器仅保留数据收集。因此,向视图中添加一个字段,以保留用于在视图中填充视图的数据元素的引用。换句话说:
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;
}
}
现在,视图者知道适配器的哪个元素正在使用。因此,在覆盖适配器中的绑定方法时,可以检查持有者是否已与某些数据绑定,如果数据包含视频,则可以避免绑定并强制设置已加载的视图。
@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();
}
}
请记住,如果您不管理存储的视图,这可能会导致严重的泄漏。此外,您必须定义告知数据何时是视频的方法,以及正确定义的等于方法。
答案 3 :(得分:2)
当RecyclerView包含一次未在屏幕上显示的列表时,它会多次使用一个视图(表示列表中包含大量未在屏幕上显示的项目,同时需要向上和向下滚动)。当用户滚动列表时,重复使用屏幕外项目以显示剩余的列表项,称为回收。
要停止回收项目,请在onBindViewHolder方法中调用此方法:
viewHolder.setIsRecyclable(false);
此声明停止回收视图。
要开始回收物品,请在onBindViewHolder方法中调用此方法:
viewHolder.setIsRecyclable(true);
我希望这能解决你的问题。 感谢
答案 4 :(得分:0)
尝试将此用于该特定位置:
holder.setIsRecyclable(false);
希望这可能会有所帮助。
答案 5 :(得分:0)
处理不回收物品的最佳方法是在recyclerview中,此答案将解决您的问题。
答案 6 :(得分:-8)
如果您使用的是查询,则可以使用
query.limit(//no of items you want to show in your RecyclerView)
试一试。
或Plese发布您的QueryCode