我使用DraggablePanel库(https://github.com/pedrovgs/DraggablePanel)来促进类似YouTube的视频播放器.如果您不熟悉此功能,它基本上允许用户将当前正在播放的视频缩小为停靠在屏幕一角的小缩略图.
不幸的是(我不太确定这是上述库的问题)我注意到如果我在VideoView的父视图上应用X和Y比例,VideoView本身将不会调整其内容的大小以匹配.
请参见下面的屏幕截图,其中VideoView处于自然规模,然后将其父视图缩小到约0.6:0.6.您应该注意到,在缩放的屏幕截图中,VideoView已裁剪其内容而不是调整大小以适应.
所以当我的父级比例发生变化时,我试图在VideoView上强制宽度和高度.互联网上有一些关于覆盖VideoView尺寸的例子 – 但这是我的简单版本:
public class ScalableVideoView extends VideoView {
private int mVideoWidth;
private int mVideoHeight;
public ScalableVideoView(Context context) {
super(context);
}
public ScalableVideoView(Context context,AttributeSet attrs) {
super(context,attrs);
}
public ScalableVideoView(Context context,AttributeSet attrs,int defStyle) {
super(context,attrs,defStyle);
mVideoWidth = 0;
mVideoHeight = 0;
}
@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
if (mVideoWidth > 0 && mVideoHeight > 0) {
// If a custom dimension is specified,force it as the measured dimension
setMeasuredDimension(mVideoWidth,mVideoHeight);
} else {
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
}
public void changeVideoSize(int width,int height) {
mVideoWidth = width;
mVideoHeight = height;
getHolder().setFixedSize(width,height);
requestLayout();
invalidate();
}
}
包含VideoView的片段负责在从DraggablePanel库收到有关比例变化的通知时调用其上的changeVideoSize.此时,我根据提供的比例值计算一对新的宽度和高度. (比例从0f到1f)
public void setVideoViewScale(float scaleX,float scaleY) {
if (mMaxVideoWidth == 0) {
mMaxVideoWidth = mVideoView.getWidth();
}
if (mMaxVideoHeight == 0) {
mMaxVideoHeight = mVideoView.getHeight();
}
if (mMaxVideoWidth > 0) {
mVideoView.changeVideoSize((int) (scaleX * mMaxVideoWidth),(int) (scaleY * mMaxVideoHeight));
}
}
不幸的是,这会产生一些非常有趣似乎VideoView的视频部分正在适当缩放 – 但VideoView的边界似乎缩放太快(导致视频缩小和裁剪).
为了进一步演示,这里有两个视频:
> https://github.com/npike/so_scalevideoview/blob/master/demo_videos/so_videoview_noscale.mp4
> https://github.com/npike/so_scalevideoview/blob/master/demo_videos/so_videoview_scale.mp4
我还将此示例项目上传到GitHub,以便您可以看到完整的代码:
https://github.com/npike/so_scalevideoview
这是修复问题的代码.将changeVideoSize(int width,int height)方法编辑为:
public void changeVideoSize(int width,int height){
mVideoWidth = width;
mVideoHeight = height;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width,height);
lp.addRule(RelativeLayout.CENTER_HORIZONTAL,RelativeLayout.TRUE);
lp.addRule(RelativeLayout.CENTER_VERTICAL,RelativeLayout.TRUE);
setLayoutParams(lp);
requestLayout();
invalidate();
}
随着视图的失效,您强制VideoView使用新的布局参数重绘整个视图.