つるやInstagramアプリなどの動画でリストを実装しようとしています。リスト アイテムが表示されているか完全に表示されているときにビデオが再生され、リスト アイテムが非表示になるとビデオが一時停止します。メディア プレーヤーで textureview を使用して URL からビデオを再生し、recyclerview のリスト項目として追加しました。以下は私のコードです。
VideosAdapter クラス:
public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.ViewHolder> {
Context context;
private ArrayList<String> urls;
public static class ViewHolder extends RecyclerView.ViewHolder {
public LinearLayout layout;
public TextView textView;
public ViewHolder(View v) {
super(v);
layout = (LinearLayout) v.findViewById(R.id.linearLayout);
textView = (TextView) v.findViewById(R.id.textView);
}
}
public VideosAdapter(Context context, ArrayList<String> urls) {
this.context = context;
this.urls = urls;
}
// Create new views (invoked by the layout manager)
@Override
public VideosAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_main, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String url = urls.get(position);
holder.textView.setText(url);
playVideo(holder, url);
}
@Override
public int getItemCount() {
return urls.size();
}
private void playVideo(ViewHolder holder, String url)
{
final CustomVideoPlayer vid = new CustomVideoPlayer(String.valueOf(url), context);
holder.layout.addView(vid);
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
vid.changePlayState();
}
});
}
}
CustomVideoPlayer クラス:
public class CustomVideoPlayer extends TextureView implements TextureView.SurfaceTextureListener
{
Context context;
String url;
MediaPlayer mp;
Surface surface;
SurfaceTexture s;
public CustomVideoPlayer(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
}
public CustomVideoPlayer(String ur, Context context)
{
super(context);
this.setSurfaceTextureListener(this);
this.url = ur;
this.context = context;
}
@Override
public void onSurfaceTextureAvailable(final SurfaceTexture surface, int arg1, int arg2) {
this.s = surface;
Log.d("url", this.url);
startVideo(surface);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
return true;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) {
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
}
public void setVideo(String url)
{
this.url = url;
}
public void startVideo(SurfaceTexture t)
{
this.surface = new Surface(t);
this.mp = new MediaPlayer();
this.mp.setSurface(this.surface);
try {
Uri uri = Uri.parse(this.url);
this.mp.setDataSource(url);
this.mp.prepareAsync();
this.mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
mp.start();
}
});
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
try {
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
public void changePlayState()
{
if(this.mp.isPlaying())
this.mp.pause();
else
this.mp.start();
}
}
このコードを実行すると、複数の問題が発生します。
1) 最初の 2 つのアイテム/動画がバッファリングされ、正常に再生されます。しかし、スクロールすると3番目のビデオがロードされず、最初のビデオもリストから削除されます。
2) スクロール ビデオ/リスト アイテムでは、既にバッファリングされたアイテムのバッファリングが再び開始されます。
3) 高速スクロール リストではラグが発生し、スタックしてクラッシュします。
リストのスクロールとビデオの再生中に取得したlogcatの画像が添付されています。
誰でもこれを案内できますか?つるアプリのようなリストを作成する正しい方法は何ですか?