安卓 ListView 视频列表

4
我正在开发一个项目,需要包括来自互联网各个视频源(包括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();
    }
}

应用程序长这样:

enter image description here


你能发布代码吗?可能存在结构问题。也许你正在重新创建或重新初始化你的视频播放器对象? - Emre Aktürk
@EmreAktürk 在这里,更新了帖子。 - ZassX
你的应用程序运行速度快,但是当你不断向下滚动时变得越来越慢吗? - Emre Aktürk
不,性能始终都是一样的(卡顿)。肯定有办法的,因为这个应用程序就像9gag应用程序一样,可以播放gif并且运行非常流畅。 - ZassX
视频会自动播放吗?还是需要点击才能播放? - Emre Aktürk
显示剩余3条评论
1个回答

2
我认为每当绘制新行时,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方法中添加日志并检查结果。

我在等待回复。

祝你好运。


谢谢您,它帮助我很大程度上解决了滚动卡顿的问题。虽然还不是完美的,但比之前好多了。 - ZassX
很高兴能帮上忙。你需要努力改进它,使其更加流畅 :( - Emre Aktürk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接