【问题标题】:Videos showing in wrong order when using TextureView in a ListView在 ListView 中使用 TextureView 时视频显示顺序错误
【发布时间】:2014-08-28 14:04:04
【问题描述】:

我有一个列表视图,它在某些行中显示视频,因此用户可以使用 TextureView 通过列表视图观看视频。到目前为止,视频可以正确加载和播放,但在滚动时它们似乎有时会以错误的顺序显示。我相信这是由于适配器回收视图,但我不知道如何解决这个问题。

这是我的实现

有一个 getView 处理视图的渲染,然后有一个由 getView 启动的 AsyncTask 来为每个视图设置 MediaPlayer。

@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;
}

【问题讨论】:

    标签: android android-arrayadapter android-mediaplayer surfaceview glsurfaceview


    【解决方案1】:

    这是因为您在onSurfaceTextureAvailable 中创建的AsyncTask 实例可能不会按顺序完成,并且当您滚动时,为新的view 创建的线程可能会在回收的view 的线程之前完成(所以旧的数据已加载)。

    我设法通过创建一个我在滚动时终止的单个线程池来解决这个问题。

    另外,thisListView 加载的终极问题。

    【讨论】:

    • 使用 AsyncTasks 我相信你不能重用实例,必须创建一个新实例。如果我要在我的 ViewHolder 类中添加一个实例会更好吗?您能否就我的情况更具体一些,也许还有一些伪代码。
    • 我尝试为我的 SetVideotask 使用全局变量并在开始新任务之前取消,但这不起作用。
    猜你喜欢
    • 2019-01-15
    • 1970-01-01
    • 2015-09-07
    • 2012-07-30
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多