Android ListView 视频列表

Android ListView list of videos

我正在做一个项目,该项目应该包括来自整个互联网的视频列表(视频来源不同——youtube、vimeo、facebook、服务器上托管的视频……)。我正在尝试制作一个 ListView,其中项目有一个视频播放器和一些描述当用户点击播放按钮时,视频开始播放。我举了一个例子,我使用 VideoView 作为播放器,但很快意识到性能不是很好 - 滚动非常滞后。

所有这些都位于 RecyclerView 中,一切都由 RecyclerViewAdapter 处理。

我想知道是否有人对此有任何经验,最佳做法是什么。

编辑

我的代码

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();
    }
}

}

应用看起来像这样:

我认为 VideoView 会在绘制新行时自动调用 prapare 方法。因此,每次滚动时,视频都会开始和暂停。您为显示缩略图所做的技巧并不实用。它可能会极大地影响性能。尽量避免并检查性能如何变化。您还可以通过 Android Studio 的底部布局控制 CPU 的使用。

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();
        }
    });

下面几行也需要调用一次。否则,当您每次滚动时将它们写在 onBindView 中时,都会创建新的侦听器并且会占用内存。

我们需要验证问题是否属实。您可以尝试在onPrepare方法体中添加一个log,查看结果。

我正在等待回复。

祝你好运。