Android中关于ScrollView中有视频播放器VideoView时问题的总结

本文总结了在Android ScrollView中使用VideoView时遇到的横竖屏切换问题,包括播放器高度无效、横屏切竖屏后ScrollView位置恢复、滚动时暂停和恢复播放,以及ListView初始位置问题的解决方案,提供了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.横竖屏切换问题
问题描述:
网上很多封装的视频播放器,也有横竖屏切换,但是发现在Scrollview中时横屏的高度会无效,因为Scrollview是可滚动控件
解决方案:
1)在切换前记录原始播放器的高度传给播放器如(videoPlayer),并告诉影响播放器全屏显示的其它控件列表(List)和播放器所在的父控件
2)竖屏切横屏,设置播放器的LayoutParams的宽高为屏幕的高宽,Gone掉其它控件,播放器的父控件的margin和padding设置为0
3)横屏切竖屏,恢复保存的原始宽高,显示其它控件,恢复父控件的margin和padding
实例代码如下:

/**
 * 竖屏转横屏
 */
public void portrait2landscape(boolean isAuto) {
    changeScreen(isFullScreen);
    ViewGroup.LayoutParams params = this.getLayoutParams();
    params.width = DisplayUtil.getScreenHeight(mContext);
    params.height = DisplayUtil.getScreenWidth(mContext);
    this.setLayoutParams(params);
    if (!isAuto) {
        //强制横屏
        mContext.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    changeScreenBtn.setImageResource(R.drawable.ic_player_suoxiao);
    rlTitile.setVisibility(VISIBLE);
}

/**
 * 横屏转竖屏
 */
public void landscape2portrait(boolean isAuto) {
    changeScreen(isFullScreen);
    ViewGroup.LayoutParams params = this.getLayoutParams();
    if (initHeight != 0) {
        params.height = initHeight;
    } else {
        params.height = 405;
    }
    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
    this.setLayoutParams(params);
    if (!isAuto) {
        mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
    //start-恢复状态栏显示
    WindowManager.LayoutParams attr = mContext.getWindow().getAttributes();
    attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
    mContext.getWindow().setAttributes(attr);
    mContext.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    //end
    changeScreenBtn.setImageResource(R.drawable.ic_player_quanping);
    rlTitile.setVisibility(GONE);
}

2.横屏切竖屏后如何恢复Scrollview到原来滚动的位置
问题描述:横屏切竖屏后,Scrollview原来的位置恢复到顶部了,导致本来可见的视频播放器不可见了
解决方案:
1)要实时监控ScrollView的滚动情况,这个网上有很多一般是自定义一个ObserableScrollView
2)在点击横竖屏切换前(准备切换,但是还没有切换的时候)记录滚动的位置,为什么要强调时机呢?因为当完成横竖屏切换时也会调用onScrollChanged方法
而此时的滚动的x,y坐标会为0.所以我们要在切换前记录下原始位置。
3)在横屏切回竖屏后调用ScrollView的scrollTo(x,y)回到原始位置
4)注意:scrollTo要通过异步的方式调用,否则充值的ScrollView还没有完全成型你调用这个压根不起作用。
实例代码:

public interface OnScreenChangeListener {
    void beforeChange(boolean isFullScreen);
    void afterChange(boolean isFullScreen);
}
isFullScreen = !isFullScreen;
if (mOnScreenChangeListener != null) {
    mOnScreenChangeListener.beforeChange(isFullScreen);
}
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
    portrait2landscape(false);
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    landscape2portrait(false);
}
if (mOnScreenChangeListener != null) {
    mOnScreenChangeListener.afterChange(isFullScreen);
}

videoPlayer.setmOnScreenChangeListener(new VideoPlayer.OnScreenChangeListener() {
    @Override
    public void beforeChange(boolean isFullScreen) {
        if(isFullScreen){
            //记录之前的位置
            vpScrollX = imScrollX;
            vpScrollY = imScrollY;
        }
    }

    @Override
    public void afterChange(boolean isFullScreen) {
        //恢复之前的位置
        if(!isFullScreen){
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    svContent.scrollTo(vpScrollX,vpScrollY);
                }
            },1);
        }
    }
});

3.如何实现当ScrollView滚动时,播放器可见和不可见时能自动暂定和恢复播放
问题描述:当ScrollView滚动时,如果不处理播放器将一直播,会造成一种恐怖的现象,我压根没看视频,单背后总有声音。
解决方案:
1)要确定是在滚动过程中实现,就要时刻监控ScrollView的滚动情况,这个上面已有提及
2)如果把控播放器的可见于不可见的时机,经过网络搜索与无脑尝试,最后可以通过一个工具静态方法实现,其思路利用View的getLocalVisbleRect
来实现,其参数就是屏幕的矩形 new Rect(0,0,screenWidth,screenHeight)
实例代码:

public static Boolean checkIsVisible(Context context, View view) {
   // 如果已经加载了,判断广告view是否显示出来,然后曝光
   int screenWidth = getScreenWidth(context);
   int screenHeight = getScreenHeight(context);
   Rect rect = new Rect(0, 0, screenWidth, screenHeight);
   int[] location = new int[2];
   view.getLocationInWindow(location);
   if (view.getLocalVisibleRect(rect)) {
      return true;
   } else {
      //view已不在屏幕可见区域;
      return false;
   }
}
svContent.setScrollViewListener(new ScrollViewListener() {
    @Override
    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
        if(svContent == scrollView){
            imScrollX = x;
            imScrollY = y;
        }
        if(null != videoPlayer){
            if(DisplayUtil.checkIsVisible(mContext,videoPlayer)){
                videoPlayer.reStartPlay();
            }else{
                videoPlayer.onPausePlayer();
            }
        }
    }
});

4.ScrollView中有ListView时起始位置为ListView底部的问题解决方案(无代码不编程)。注意调用时机是在listview数据填充后哦

mlvInfo.setFocusable(false);
if(null != svContent){
    svContent.smoothScrollTo(0,0);
}

以上是本猴实战中遇到的坑,特此记录以便应付日益渐摔的记忆,如有疑问可留言,原与君共学习同进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值