本文介绍了如何不只回收我的recyclerview的前两个视图或任何项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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的前两个视图或任何项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 13:59