Android SurfaceView预览变形完美解决方法
这个问题百度上一搜一大把,基本上都是说找到和SurfaceView的比例相近的camera预览尺寸,但是发现预览时候还是差了点意思,具体看下面这个回调就知道是为什么了。
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){
Log.i(TAG,"surfaceChanged:"+width+""+height);
}
从上面的回调打印的数据知道其实取相近的比例解决不了根本问题。
所以,对于此类的解决方法我只想说仅仅相近有神马用。
那么既然知道surfaceChanged的宽高就是SurfaceView的渲染宽高,那么想办法把surfaceChanged里的宽高比弄成和camera比例一样不就行了嘛,所以看SurfaceView的源码:
protectedvoidupdateWindow(booleanforce,booleanredrawNeeded){
...代码省略
intmyWidth=mRequestedWidth;
if(myWidth<=0)myWidth=getWidth();
intmyHeight=mRequestedHeight;
if(myHeight<=0)myHeight=getHeight();
...代码省略
if(creating||formatChanged||sizeChanged
||visibleChanged||realSizeChanged){
if(DEBUG)Log.i(TAG,System.identityHashCode(this)+""
+"surfaceChanged--format="+mFormat
+"w="+myWidth+"h="+myHeight);
if(callbacks==null){
callbacks=getSurfaceCallbacks();
}
for(SurfaceHolder.Callbackc:callbacks){
c.surfaceChanged(mSurfaceHolder,mFormat,myWidth,myHeight);
}
}
...代码省略
}
可以看到宽高其实就是调用的View的getHeight和getWidth或者是mRequestedWidth和mRequestedHeight。
熟悉了View的自定义就知道getHeight和getWidth都是和View的onMeasure息息相关,所以想到重写onMeasure方法。
再从源码看到关于mRequestedWidth和mRequestedHeight的赋值
@Override
publicvoidsetFixedSize(intwidth,intheight){
if(mRequestedWidth!=width||mRequestedHeight!=height){
mRequestedWidth=width;
mRequestedHeight=height;
requestLayout();
}
}
以下是完整类代码:
publicclassResizeAbleSurfaceViewextendsSurfaceView{
privateintmWidth=-1;
privateintmHeight=-1;
publicResizeAbleSurfaceView(Contextcontext){
super(context);
}
publicResizeAbleSurfaceView(Contextcontext,AttributeSetattrs){
super(context,attrs);
}
publicResizeAbleSurfaceView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
if(-1==mWidth||-1==mHeight){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
else{
setMeasuredDimension(mWidth,mHeight);
}
}
publicvoidresize(intwidth,intheight){
mWidth=width;
mHeight=height;
getHolder().setFixedSize(width,height);
requestLayout();
invalidate();
}
}
实例化的时候记得调用resize方法就好了。
注意和camera的预览尺寸比例一致,且宽高记得传正确,不然可能不全屏
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。