我正在制作一个项目,其中应包括来自互联网的视频列表(视频来源不同 - youtube,vimeo,facebook,托管在服务器上的视频......)。我正在尝试创建一个ListView,其中item有一个视频播放器和一些描述当用户点击播放按钮时,视频开始播放。我做了一个例子,我使用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();
}
}
}
App看起来像这样:
答案 0 :(得分: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方法主体并检查结果。
我在等待回应。
祝你好运。