当前位置: 移动技术网 > 移动技术>移动开发>Android > 【Android】Jetpack全组件实战开发短视频应用App(二十三)

【Android】Jetpack全组件实战开发短视频应用App(二十三)

2020年07月13日  | 移动技术网移动技术  | 我要评论

前言

这一篇我们主要是完成视频的无缝续播,从列表到详情,从详情返回列表,我们看下效果
在这里插入图片描述

实现

分三步:
第一步:视频切换视频不暂停,防止画面卡顿
第二步:公用一个播放器,去除缓冲效果
第三步:使用新的PlayerView,防止原来View缺失造成黑色现象

首先我们要做的就是页面切换的时候不暂停视频,我们一般是在onPause()方法中调用视频的暂停方法,所以这里我们需要区分下,如果是点击跳转到详情我们就部调用这个暂停方法,这里我们用一个boolean变量shouldPause区分,默认是true,接着我们在onPause方法中坐下判断,这里只要是需要用到无缝续播的地方我们都这样做

    @Override
    public void onPause() {
        //如果是跳转到详情页,咱们就不需要 暂停视频播放了
        //如果是前后台切换 或者去别的页面了 都是需要暂停视频播放的
        if (shouldPause) {
            playDetector.onPause();
        }
        super.onPause();
    }

那我们什么时候把这个值变成false呢?就是在我们点击这个这条item的时候,所以我们需要在FeedAdapter点击事件加一个方法,

 holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
				//....
                onStartFeedDetailActivity(feed);
               //....
            }
        });
public void onStartFeedDetailActivity(Feed feed) {

    }

需要 把这个变量变成false的地方就复写这个方法即可,比如我们的HomeFragment

  @Override
            public void onStartFeedDetailActivity(Feed feed) {
                boolean isVideo = feed.itemType == Feed.TYPE_VIDEO;
                shouldPause = !isVideo;
            }

这样我们就先完成了第一步,切换视频视频不暂停,接下来我们 就要完成第二步,我们需要公用一个播放器,这个比较简单,就是我们通过首页传递过来的category获取播放器实例即可

第三步是需要一个新的PlayerView,这里我们跳转过去需要全屏播放,所以我们需要写一个FullScreenPlayerView,我们 之前写过ListPlayerView,我们只需要继承它然后复写一些方法即可

public class FullScreenPlayerView extends ListPlayerView {
    private PlayerView exoPlayerView;

    public FullScreenPlayerView(@NonNull Context context) {
        this(context, null);
    }

    public FullScreenPlayerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FullScreenPlayerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public FullScreenPlayerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        exoPlayerView = (PlayerView) LayoutInflater.from(context).inflate(R.layout.layout_exo_player_view, null, false);
    }

    @Override
    protected void setSize(int widthPx, int heightPx) {
        if (widthPx >= heightPx) {
            super.setSize(widthPx, heightPx);
            return;
        }

        int maxWidth = PixUtils.getScreenWidth();
        int maxHeight = PixUtils.getScreenHeight();

        ViewGroup.LayoutParams params = getLayoutParams();
        params.width = maxWidth;
        params.height = maxHeight;
        setLayoutParams(params);

        FrameLayout.LayoutParams coverLayoutParams = (LayoutParams) cover.getLayoutParams();
        coverLayoutParams.width = (int) (widthPx / (heightPx * 1.0f / maxHeight));
        coverLayoutParams.height = maxHeight;
        coverLayoutParams.gravity = Gravity.CENTER;
        cover.setLayoutParams(coverLayoutParams);
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        if (mHeightPx > mWidthPx) {
            int layoutWidth = params.width;
            int layoutheight = params.height;
            ViewGroup.LayoutParams coverLayoutParams = cover.getLayoutParams();
            coverLayoutParams.width = (int) (mWidthPx / (mHeightPx * 1.0f / layoutheight));
            coverLayoutParams.height = layoutheight;

            cover.setLayoutParams(coverLayoutParams);
            if (exoPlayerView != null) {
                ViewGroup.LayoutParams layoutParams = exoPlayerView.getLayoutParams();
                if (layoutParams != null && layoutParams.width > 0 && layoutParams.height > 0) {
                    float scalex = coverLayoutParams.width * 1.0f / layoutParams.width;
                    float scaley = coverLayoutParams.height * 1.0f / layoutParams.height;

                    exoPlayerView.setScaleX(scalex);
                    exoPlayerView.setScaleY(scaley);
                }
            }
        }
        super.setLayoutParams(params);
    }

    @Override
    public void onActive() {
        PageListPlay pageListPlay = PageListPlayManager.get(mCategory);
        PlayerView playerView = exoPlayerView;//pageListPlay.playerView;
        PlayerControlView controlView = pageListPlay.controlView;
        SimpleExoPlayer exoPlayer = pageListPlay.exoPlayer;
        if (playerView == null) {
            return;
        }

        //主动关联播放器与exoplayerview
        pageListPlay.switchPlayerView(playerView, true);
        ViewParent parent = playerView.getParent();
        if (parent != this) {

            if (parent != null) {
                ((ViewGroup) parent).removeView(playerView);
            }

            ViewGroup.LayoutParams coverParams = cover.getLayoutParams();
            this.addView(playerView, 1, coverParams);
        }

        ViewParent ctrlParent = controlView.getParent();
        if (ctrlParent != this) {
            if (ctrlParent != null) {
                ((ViewGroup) ctrlParent).removeView(controlView);
            }
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.BOTTOM;
            this.addView(controlView, params);
        }

        //如果是同一个视频资源,则不需要从重新创建mediaSource。
        //但需要onPlayerStateChanged 否则不会触发onPlayerStateChanged()
        if (TextUtils.equals(pageListPlay.playUrl, mVideoUrl)) {
            onPlayerStateChanged(true, Player.STATE_READY);
        } else {
            MediaSource mediaSource = PageListPlayManager.createMediaSource(mVideoUrl);
            exoPlayer.prepare(mediaSource);
            exoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
            pageListPlay.playUrl = mVideoUrl;
        }
        controlView.show();
        controlView.setVisibilityListener(this);
        exoPlayer.addListener(this);
        exoPlayer.setPlayWhenReady(true);
    }

    @Override
    public void inActive() {
        super.inActive();
        PageListPlay pageListPlay = PageListPlayManager.get(mCategory);
        //主动切断exoplayer与视频播放器的联系
        pageListPlay.switchPlayerView(exoPlayerView, false);
    }
}

简单解释下,我们通过复写setSize方法设置PlayerView的宽高和封面的宽高,exoplayer不需要在这里设置宽高,因为这个时候还没有添加到playerview中,我们是在onActive方法中添加的,同时它的宽和高和视频的封面宽和高一致;我们通过复写onActive方法实现播放器和我们这个PlayerView的关联,复写inActive方法切断 联系

  public void switchPlayerView(PlayerView newPlayerView, boolean attach) {
        playerView.setPlayer(attach ? null : exoPlayer);
        newPlayerView.setPlayer(attach ? exoPlayer : null);
    }

本文地址:https://blog.csdn.net/Greathfs/article/details/107297218

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网