如何在 RecyclerView.SCROLL_STATE_DRAGGING 时暂停 ExoPlayer playerView 并在 Destroy 时释放播放器

问题描述 投票:0回答:1

我想实现一个与 Instagram feed 类似的 RecyclerView,其中包含图像和视频项。我已经成功实现了 recyclerView 来显示图像和视频项目,但是当 onScrollListener 开启时,我遇到了暂停视频项目的问题

RecyclerView.SCROLL_STATE_DRAGGING
我正在使用 ExoPlayer 库作为视频播放器”

因此,如果播放视频并且 recyclerView 没有暂停,即使从列表中播放另一个视频,它也会继续播放该视频。使多个视频同时播放。

下面是我的实现适配器

public class RecyclerAdapter extends RecyclerView.Adapter {

    private ArrayList<ListModel> listModelList;
    private Context context;

    SimpleExoPlayer exoPlayer;

    public RecyclerAdapter(ArrayList<ListModel> listModelList, Context context) {
        this.listModelList = listModelList;
        this.context = context;
    }

    @Override
    public int getItemViewType(int position) {
        if (listModelList.get(position).getDescription().equalsIgnoreCase("video")) {
            return 1;
        } else {
            return 0;
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view;

        if (viewType == 0) {
            view = inflater.inflate(R.layout.recycler_item, parent, false);
            return new AdsViewHolder(view);
        } else {
            view = inflater.inflate(R.layout.video_item, parent, false);
            return new VideoVH(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
        ListModel listModel = listModelList.get(position);

        if (listModel.getDescription().equalsIgnoreCase("video")) {
            VideoVH videoVH = (VideoVH) holder;
            initPlayer(((VideoVH) holder).playerView, listModel.getMedia_url(), ((VideoVH) holder).progressBar);
            ((VideoVH) holder).titleText.setText(listModel.getTitle());
            ((VideoVH) holder).descText.setText(listModel.getDescription());

            //Play video
        } else {
            AdsViewHolder adsViewHolder = (AdsViewHolder) holder;

            ((AdsViewHolder) holder).titleText.setText(listModel.getTitle());
            ((AdsViewHolder) holder).descText.setText(listModel.getDescription());
            Glide.with(context)
                    .load(listModel.getMedia_url())
                    .into(((AdsViewHolder) holder).imageView);
        }
    }

    private void initPlayer(final PlayerView playerView, String uri, final ProgressBar progressBar) {


        TrackSelector trackSelector = new DefaultTrackSelector();

        exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);

        playerView.setPlayer(exoPlayer);
        exoPlayer.setPlayWhenReady(false);
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "ExoRecyclerView"));

        MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(uri));

        exoPlayer.prepare(videoSource);

        playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
        exoPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
        exoPlayer.seekTo(500);

        exoPlayer.addListener(new Player.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                switch (playbackState) {

                    case Player.STATE_BUFFERING:
//                        Log.e(TAG, "onPlayerStateChanged: Buffering video.");
                        if (progressBar != null) {
                            progressBar.setVisibility(VISIBLE);
                        }

                        break;
                    case Player.STATE_ENDED:
                        break;
                    case Player.STATE_IDLE:

                        break;
                    case Player.STATE_READY:
//                        Log.e(TAG, "onPlayerStateChanged: Ready to play.");
                        if (progressBar != null) {
                            progressBar.setVisibility(GONE);
                        }
                        break;
                    default:
                        break;
                }

            }

            @Override
            public void onRepeatModeChanged(int repeatMode) {

            }

            @Override
            public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }

            @Override
            public void onPositionDiscontinuity(int reason) {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }

            @Override
            public void onSeekProcessed() {

            }
        });
    }

    @Override
    public int getItemCount() {
        return listModelList.size();
    }

    class AdsViewHolder extends RecyclerView.ViewHolder {

        ImageView imageView;
        TextView titleText, descText;

        public AdsViewHolder(@NonNull View itemView) {
            super(itemView);

            imageView = itemView.findViewById(R.id.thumbnail);
            descText = itemView.findViewById(R.id.desc);
            titleText = itemView.findViewById(R.id.title);
        }
    }

    class VideoVH extends RecyclerView.ViewHolder {


        PlayerView playerView;
        TextView titleText, descText;
        ConstraintLayout VV;
        ProgressBar progressBar;
        ImageView volumeControl;

        public VideoVH(@NonNull View itemView) {
            super(itemView);

            playerView = itemView.findViewById(R.id.playerView);
            descText = itemView.findViewById(R.id.desc);
            titleText = itemView.findViewById(R.id.title);
            volumeControl = itemView.findViewById(R.id.volume_control);
            VV = itemView.findViewById(R.id.parent);
            progressBar = itemView.findViewById(R.id.progressBar);
        }
    }

}

MainActivity 实现

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    ArrayList<ListModel> listModelList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = findViewById(R.id.recyclerView);

        ListModel listModel = new ListModel();
        listModelList.add(new ListModel("One test",
                "https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
        listModelList.add(new ListModel("One test",
                "https://res.cloudinary.com/dqrs5xew4/video/upload/v1595538345/HNG/b5bc3f170b7d5c388410bcca0a501ecd_lnhzwn.mp4", "video"));
        listModelList.add(new ListModel("One test",
                "https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
        listModelList.add(new ListModel("One test",
                "https://res.cloudinary.com/dqrs5xew4/video/upload/v1595538331/HNG/VID-20180713-WA0009_esbmff.mp4", "video"));
        listModelList.add(new ListModel("One test",
                "https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
        initRecyclerView();
    }

    private void initRecyclerView() {
        // use a linear layout manager
        LinearLayoutManager layoutManager =
                new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(layoutManager);

        RecyclerAdapter mAdapter = new RecyclerAdapter(listModelList, MainActivity.this);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.notifyDataSetChanged();
    }
}

模型类

public class ListModel {

    private String title;
    private String media_url;
    private String description;

    public ListModel(String title, String media_url, String description) {
        this.title = title;
        this.media_url = media_url;
        this.description = description;
    }

    public ListModel() {
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getMedia_url() {
        return media_url;
    }

    public void setMedia_url(String media_url) {
        this.media_url = media_url;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

我在这里和 youtube 上经历了几个问题,但它们都在 recyclerView 中实现了单一视图类型。

有什么建议我可以在 recyclerView 滚动时控制视频播放器吗?或者是我可以实现像 RecyclerView 这样的 Instagram feed 的更好方法

java android video android-recyclerview exoplayer2.x
1个回答
0
投票

//您可以添加此内容,但您应该知道它并不适用于所有情况。

Recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
            if (adapter != null && adapter.player != null) {
                adapter.player.setPlayWhenReady(false);
            }
        }
    }
});

© www.soinside.com 2019 - 2024. All rights reserved.