Android ListView list of videos

14,767

I think VideoView is calling prapare method automatically whenever new row is drawn. So each time you scroll, video starts and pauses. Trick you have done to show thumbnail is not practical. It may hugely effect performance. Try to avoid and check how performance changes. Also you can control your CPU usage from bottom layout of Android Studio.

holder.mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.mVideoView.start();
        }
    });

    holder.mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            // This is just to show image when loaded
            mp.start();
            mp.pause();
        }
    });

    holder.mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            // setLooping(true) didn't work, thats why this workaround
            holder.mVideoView.setVideoPath(tempVideo.getGifUrl());
            holder.mVideoView.start();
        }
    });

Also following lines are need to called once. Otherwise, as you wrote them inside onBindView each time you scroll new listeners are created and it costs to memory.

We need to verify if problem is true or not. You can try to add a log to onPrepare method body and check the results.

I am waiting for response.

Good luck there.

Share:
14,767
ZassX
Author by

ZassX

Mobile developer

Updated on June 27, 2022

Comments

  • ZassX
    ZassX almost 2 years

    I am working on a project which should include a list of videos from allover the internet (video sources are different - youtube, vimeo, facebook, videos hosted on servers, ...). I am trying to make a ListView, where item has a video player and some description When user clicks on play button the video starts playing. I made one example, where I use VideoView as player, but soon realised that the performance is not very good - scrolling is very laggy.

    All of this is located in a RecyclerView and everything is handled by RecyclerViewAdapter.

    I am wondering if someone has any experience with this and what is the best practice.

    EDIT

    My code

    public class ListFragment extends Fragment {
    
    ArrayList<Video> videoList;
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        RecyclerView rv = (RecyclerView) inflater.inflate(
                R.layout.fragment_cheese_list, container, false);
    
        videoList = SplashActivity.videoList;
    
        setupRecyclerView(rv);
        return rv;
    }
    
    private void setupRecyclerView(RecyclerView recyclerView) {
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
        recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(getActivity(), videoList));
    }
    
    public class SimpleStringRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
    
        private final TypedValue mTypedValue = new TypedValue();
        private int mBackground;
        private ArrayList<Video> mVideoList;
    
        public class ViewHolder extends RecyclerView.ViewHolder {
            public String mBoundString;
    
            public final View mView;
            public final VideoView mVideoView;
            public final TextView mTextView;
            public final TextView mCountTextView;
            public final TextView mHintTextView;
            public final Button mPlayButton;
            public final ImageView mFavoriteIcon;
            public final RelativeLayout mRelativeLayout;
            public final ProgressBar mProgressBar;
    
            public ViewHolder(View view) {
                super(view);
                mView = view;
                mVideoView = (VideoView) view.findViewById(R.id.listVideoView);
                mTextView = (TextView) view.findViewById(R.id.gifTitleTextView);
                mCountTextView = (TextView) view.findViewById(R.id.countTextView);
                mHintTextView = (TextView) view.findViewById(R.id.hintTextView);
                mPlayButton = (Button) view.findViewById(R.id.playButton);
                mFavoriteIcon = (ImageView) view.findViewById(R.id.favoriteImageView);
                mRelativeLayout = (RelativeLayout) view.findViewById(R.id.relativeLayout);
                mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
            }
    
            @Override
            public String toString() {
                return super.toString() + " '" + mTextView.getText();
            }
        }
    
        public SimpleStringRecyclerViewAdapter(Context context, ArrayList<Video> videoList) {
            context.getTheme().resolveAttribute(R.attr.selectableItemBackground, mTypedValue, true);
            mVideoList = videoList;
            mBackground = mTypedValue.resourceId;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item, parent, false);
            view.setBackgroundResource(mBackground);
            return new ViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
    
            final Video tempVideo = mVideoList.get(position);
    
            holder.mBoundString = tempVideo.getGifTitle();
            holder.mTextView.setText(tempVideo.getGifTitle());
    
            float count = tempVideo.getCount();
            String countText = "";
    
            if (count >= 1000)
                countText = String.format("%.1f", count / 1000) + "k";
            else
                countText = String.format("%d", (int)count);
    
            holder.mCountTextView.setText(countText);
    
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    holder.mVideoView.start();
                }
            });
    
            holder.mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    // This is just to show image when loaded
                    mp.start();
                    mp.pause();
                }
            });
    
            holder.mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    // setLooping(true) didn't work, thats why this workaround
                    holder.mVideoView.setVideoPath(tempVideo.getGifUrl());
                    holder.mVideoView.start();
                }
            });
    
            holder.mVideoView.setVideoPath(tempVideo.getGifUrl());
        }
    
        @Override
        public int getItemCount() {
            return videoList.size();
        }
    }
    

    }

    App looks like this:

    enter image description here