사용자가 TextureView를 사용하여 목록보기를 통해 비디오를 볼 수 있도록 일부 행에 비디오를 표시하는 Listview가 있습니다. 지금까지 동영상은 올바르게로드되고 재생되지만 스크롤하는 동안 잘못된 순서로 표시됩니다. 이것은 어댑터 재활용보기로 인해 생각하지만,이 문제를 해결하는 방법을 잘 모르겠습니다.ListView에서 TextureView를 사용할 때 비디오가 잘못된 순서로 표시됩니다.
여기에 뷰를 렌더링 한 다음 AsyncTask를 각보기의 설정에의 getView하여 MediaPlayer를 시작했다가 처리하는의 getView가 내 구현
입니다. onSurfaceTextureAvailable
에서 만든 AsyncTask
인스턴스가 순차적으로 완료되지 않을 수 있습니다 당신이 스크롤 할 때, 새로운 view
위해 만든 스레드 (그래서 이전 데이터가로드) 재활용 view
의 스레드 전에 완료 할 수 있기 때문에
@Override
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder holder;
final VoucherItem vItem = items.get(position);
if (view == null) {
view = inflater.inflate(R.layout.voucher_row, parent, false);
holder = new ViewHolder();
holder.list_img = (ImageView) view.findViewById(R.id.list_img);
holder.vid_play = (ImageView) view.findViewById(R.id.vid_play);
holder.video = (TextureView) view.findViewById(R.id.texture_video);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if (!vItem.photo.equals(""))
Picasso.with(context).load(vItem.photo).fit().centerCrop()
.into(holder.list_img);
else
Picasso.with(context).load(R.drawable.default_spuare).fit()
.centerCrop().into(holder.list_img);
if (!vItem.photo.equals("")){
holder.vid_play.setVisibility(View.GONE);
holder.video.setVisibility(View.GONE);
holder.list_img.setVisibility(View.VISIBLE);
} else {
holder.video.setVisibility(View.VISIBLE);
holder.list_img.setVisibility(View.GONE);
holder.video.setSurfaceTextureListener(new SurfaceTextureListener() {
@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,
int arg2) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
return false;
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int arg1, int arg2) {
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.vid_play.setTag(mediaPlayer);
new SetVideotask().execute(surface, vItem, mediaPlayer, holder.vid_play);
}
});
}
}
return view;
}
class SetVideotask extends AsyncTask<Object, Integer, String>{
@Override
protected String doInBackground(Object... o) {
// TODO Auto-generated method stub
final SurfaceTexture s = (SurfaceTexture) o[0];
final VoucherItem item = (VoucherItem) o[1];
final MediaPlayer mediaPlayer = (MediaPlayer) o[2];
final View v = (View) o[3];
mediaPlayer.setSurface(new Surface(s));
try {
mediaPlayer.setDataSource(item.video);
mediaPlayer.prepare();
mediaPlayer.start();
//I do this so there is a frame in the video to act as a preview
Thread.sleep(100);
mediaPlayer.pause();
mediaPlayer.setOnErrorListener(VoucherAdapter.this);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
static class ViewHolder {
ImageView list_img;
ImageView vid_play;
TextureView video;
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
return true;
}
AsyncTasks를 사용하면 인스턴스를 다시 사용할 수 없다고 생각합니다. 새 인스턴스를 만들어야합니다. ViewHolder 클래스에 인스턴스를 추가하는 것이 더 좋을까요? 내 사례와 관련해서 좀 더 자세하게 설명해 주시겠습니까? 아마도 의사 코드 일 수도 있습니다. – Amanni
새 변수를 시작하기 전에 SetVideotask에 전역 변수를 사용하고 취소하려고했지만 작동하지 않습니다. – Amanni
단서 주셔서 감사합니다. – Amanni