リストビューに複数のテクスチャ ビューがあるアプリを作成しています。私はいつも使用しているリスト配列アダプターを使用しているので、各リスト ビュー アイテムを適切にリサイクルしており、各テクスチャ ビューでビデオの正しい URL を設定していることがわかります。ただし、私のリストに 3 つ以上のビデオが含まれている場合、それらは自分自身を「複製」し始めます。つまり、4 番目のリスト項目がレンダリングされますが、ビデオ 4 ではなくビデオ 1 がレンダリングされます。また、下にスクロールして上に戻ると、そのテクスチャ ビューに関連付けられているビデオ リソースも、アダプターによって「再レンダリング」されているように変化することがあります。ビューをリサイクルすべきではありませんか? 現在の関連コード:
public class VideoListAdapter extends ArrayAdapter<videoitem> {
Context context;
int phonewidth;
int videoPlaying =0;
List<MediaPlayer> playerList = new ArrayList();
int pos;
private final ImageDownloader mDownload = new ImageDownloader();
public VideoListAdapter(Context context, int resourceId, List<videoitem> items) {
super(context, resourceId, items);
this.context = context;
phonewidth = context.getResources().getDisplayMetrics().widthPixels;
}
private class ViewHolder {
RelativeLayout wrapper;
InlineVideoPlayer videoPoster;
TextView numberOfLikes;
TextView numberOfDislikes;
ImageView UserIcon;
TextView userName;
TextView created;
ProgressBar p;
LinearLayout l;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
final videoitem rowItem = getItem(position);
pos = position;
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.videoitem,parent, false);
holder = new ViewHolder();
holder.wrapper = (RelativeLayout) convertView.findViewById(R.id.videoholder);
holder.l = (LinearLayout) convertView.findViewById(R.id.inlineVideoPlayer1);
// holder.videoPoster.setVideo("http//hub60.com/app/videos/" + rowItem.getVideo());
holder.UserIcon = (ImageView) convertView.findViewById(R.id.imageView1);
holder.numberOfDislikes = (TextView) convertView.findViewById(R.id.textView3);
holder.numberOfLikes = (TextView) convertView.findViewById(R.id.ratinglikes);
holder.created = (TextView) convertView.findViewById(R.id.textView2);
holder.userName = (TextView) convertView.findViewById(R.id.textView1);
holder.numberOfDislikes.setText(Integer.toString(position));
holder.numberOfLikes.setText(rowItem.getLikes());
holder.userName.setText(rowItem.getVideo());
holder.created.setText(rowItem.getCreated());
mDownload.download(rowItem.getIcon(), holder.UserIcon, null);
holder.l.getLayoutParams().height = phonewidth;
// vid.setLayoutParams(new LayoutParams(
// LayoutParams.MATCH_PARENT,
// LayoutParams.MATCH_PARENT));
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
holder.numberOfDislikes.setText(Integer.toString(position));
holder.numberOfLikes.setText(rowItem.getLikes());
holder.userName.setText(rowItem.getVideo());
holder.created.setText(rowItem.getCreated());
mDownload.download(rowItem.getIcon(), holder.UserIcon, null);
convertView.setId(position);
}
InlineVideoPlayer vid = new InlineVideoPlayer(rowItem.getVideo(),context);
((LinearLayout) holder.l).addView(vid);
return convertView;
}
この特定のケースでは、ホルダーが空であるかどうかを判断する if/else からそれを取り出し、最後に問題のビューを追加しました。ただし、if/else ステートメントにもそれがあり、まだ同じ動作が発生しています。
カスタム テクスチャ ビュー クラス
public class InlineVideoPlayer extends TextureView implements SurfaceTextureListener{
Context context;
MediaPlayer mp;
String url;
Surface surface;
SurfaceTexture s;
public InlineVideoPlayer(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
}
public InlineVideoPlayer(String ur,Context context)
{
super(context);
this.setSurfaceTextureListener(this);
this.url = ur;
this.context = context;
// startVideo();
//Log.d("url",this.url);
}
@Override
public void onSurfaceTextureAvailable(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(this.context, uri);
this.mp.prepareAsync();
this.mp.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
mp.seekTo(2000);
mp.start();
// mp.pause();
}
});
} 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();
}
}
}
前もって感謝します