问题描述
我正在使用recyclerview来显示和广播用户的视频.但是,当我滚动浏览回收者"视图时,我看到了我的第一个视图,该视频中的视频被回收了,因此为什么其他用户看不到它.有没有一种方法可以确保不回收第一个视图,所以我不必担心每次滚动列表时都会重置视频视图吗?
I am using a recyclerview for displaying and broadcasting videos of users. However, when I scroll through the recycler view, I see my first view, which has my video gets recycled hence why it's not visible to other users. Is there a way I can make sure that the first view is not recycled so I dont have to worry about my video view getting resetrecycled every single time I scroll through my list?
这是我的代码:在我的片段中......
Here's my code :In my fragment......
<android.support.v7.widget.RecyclerView
android:id="@+id/videoList"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/myButtonContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/myoldContainer">
...
和相应的适配器...
and the corresponding adapter...
public class GroupAdapter extends RecyclerView.Adapter<GroupAdapter.myViewHolder> {
private CopyOnWriteArrayList<Person> persons;
private Context mContext;
public GroupAdapter(@NonNull final CopyOnWriteArrayList<Person> persons , Context context) {
this.persons = persons;
this.mContext= context;
for (Person person : this.persons) {
//get names
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_person, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(layout);
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Person person = person.get(position);
final Participant participant = person.getParticipant();
if (person.getName() != null) {
holder.personName.setText(person.getName());
}
if (person.getImage() != null) {
holder.personImage.setImageBitmap(person.getImage());
} else {
holder.personImage.setImageResource(R.drawable.default_profile);
}
holder.personImage.setVisibility(View.INVISIBLE);
holder.personImage.setVisibility(View.VISIBLE);
final VideoView videoView;
if (participant.isMe) {
videoView = participant.videoStreamer.videoView;
} else {
videoView = participant.videoPlayer.videoView;
}
if (holder.personVideo.getChildCount() != 0) {
holder.personVideo.removeAllViews();
}
if (videoView.getParent() != null) {
ViewGroup parent = (ViewGroup) videoView.getParent();
parent.removeView(videoView);
}
holder.personVideo.addView(videoView, myViewHolder.videoLayoutParams);
if (person.isVideoPaused()) {
holder.personVideo.setVisibility(View.INVISIBLE);
holder.personImage.setVisibility(View.VISIBLE);
} else {
holder.personVideo.setVisibility(View.VISIBLE);
holder.personImage.setVisibility(View.INVISIBLE);
}
}
@Override
public int getItemCount() {
return persons.size();
}
public static final class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.personVideo)
public ViewGroup personVideo;
@BindView(R.id.personImage)
public ImageView personImage;
@BindView(R.id.personName)
public TextView personName;
protected static FrameLayout.LayoutParams videoLayoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
这是我在片段中对其进行设置的方式:
Here's how I am setting it in my fragment:
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
videoAdapter = new VideoAdapter(myHelper.getPeople(), getContext());
videoList.setLayoutManager(manager);
videoList.setAdapter(videoAdapter);
item_person:
item_person:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:background="@drawable/person_border"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:id="@+id/personContainer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<FrameLayout
android:id="@+id/personVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" />
<ImageView
android:id="@+id/personImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:src="@drawable/default_profile" />
<TextView
android:id="@+id/personName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#AA555555"
android:gravity="center_horizontal|bottom"
android:textColor="@color/green"
android:textSize="12sp"
android:lines="1"
android:ellipsize="end"
tools:text="[email protected]"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
具有回收视图的片段:xml
fragment with recycle view: xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout>
....
</RelativeLayout>
<include containers>...</include>
...
<android.support.v7.widget.RecyclerView
android:id="@+id/personList"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
>
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
推荐答案
我不认为不回收"视频视图实际上不会阻止滚动时视频视图被破坏.不是回收是问题,而是视图解除约束.
I don't think that "not recycling" the video view will actually stop it from being destroyed when you scroll. It's not the recycling is the problem but the view unbinding.
我认为诸如VideoView
之类的复杂组件根本不应该位于RecyclerView
内部.您可以尝试将其作为静态内容添加到顶部,这很可能会解决此问题.您可以为此使用NestedScrollView
.在这里看看: scrollview内的Recyclerview-如何滚动整个内容?
I think such complex component such as VideoView
should not be inside the RecyclerView
at all.. You can try adding it as a static content on top, which most likely will solve the issue. You can use a NestedScrollView
for that. Take a look here: Recyclerview inside scrollview- How to scroll whole content?
如果您仍然想将其保留在RecyclerView
中并禁用回收,请执行以下操作.
If you still think you want to keep it in the RecyclerView
and disable the recycling, do the following.
为视频观看项目创建单独的观看类型.这是一个例子: https://stackoverflow.com/a/26573338/3086818 .在示例中,将视频观看项目视为标题视图.
Create a separate view type for your video view items. Here is an example:https://stackoverflow.com/a/26573338/3086818. Treat your video view item as a header view from the example.
执行此操作后,将有一个RecycledViewPool
类管理RecyclerView
中项目的回收.您可以告诉它哪些视图可以回收,哪些视图不可以回收.默认情况下,它回收所有视图.要禁用视频观看项目的回收,请使用新的观看类型,如下所示:
Once you do this, there is a RecycledViewPool
class which manages the recycling of items inside a RecyclerView
. You can tell it which views to recycle and which not. By default it recycles all views. To disable recycling for your video view items use your new view type like this:
recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_VIDEO_VIEW, 0);
其中,TYPE_VIDEO_VIEW
是您使用上一个示例创建的新类型.数字0告诉RecyclerView
要回收多少个项目-在这种情况下为0,表示不回收".此处的更多信息: https://stackoverflow.com/a/36313437/3086818 .
where TYPE_VIDEO_VIEW
is the new type that you created using the previous example. The number 0 tells the RecyclerView
how many items to recycle - in this case it's 0, meaning "do not recycle". More info about this here: https://stackoverflow.com/a/36313437/3086818.
我希望这会有所帮助..祝你好运!
I hope this helps.. Good luck!
这篇关于如何不只回收我的recyclerview的前两个视图或任何项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!