软件编程
位置:首页>> 软件编程>> Android编程>> Android SurfaceView预览变形完美解决方法

Android SurfaceView预览变形完美解决方法

作者:KingVic  发布时间:2021-11-14 10:29:22 

标签:android,预览,变形

这个问题百度上一搜一大把,基本上都是说找到和SurfaceView的比例相近的camera预览尺寸,但是发现预览时候还是差了点意思,具体看下面这个回调就知道是为什么了。


 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
   Log.i(TAG, "surfaceChanged: " + width + " " + height);
 }

从上面的回调打印的数据知道其实取相近的比例解决不了根本问题

所以,对于此类的解决方法我只想说仅仅相近有神马用。

那么既然知道surfaceChanged的宽高就是SurfaceView的渲染宽高,那么想办法把surfaceChanged里的宽高比弄成和camera比例一样不就行了嘛,所以看SurfaceView的源码:


protected void updateWindow(boolean force, boolean redrawNeeded) {
   ...代码省略

int myWidth = mRequestedWidth;
   if (myWidth <= 0) myWidth = getWidth();
   int myHeight = 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.Callback c : callbacks) {
       c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
     }
   }

...代码省略
 }

可以看到宽高其实就是调用的View的getHeight和getWidth或者是mRequestedWidth和mRequestedHeight。

熟悉了View的自定义就知道getHeight和getWidth都是和View的onMeasure息息相关,所以想到重写onMeasure方法。

再从源码看到关于mRequestedWidth和mRequestedHeight的赋值


@Override
   public void setFixedSize(int width, int height) {
     if (mRequestedWidth != width || mRequestedHeight != height) {
       mRequestedWidth = width;
       mRequestedHeight = height;
       requestLayout();
     }
   }

以下是完整类代码:


public class ResizeAbleSurfaceView extends SurfaceView {

private int mWidth = -1;
 private int mHeight = -1;

public ResizeAbleSurfaceView(Context context) {
   super(context);
 }

public ResizeAbleSurfaceView(Context context, AttributeSet attrs) {
   super(context, attrs);
 }

public ResizeAbleSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);
 }

@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   if (-1 == mWidth || -1 == mHeight) {
     super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   }
   else {
     setMeasuredDimension(mWidth, mHeight);
   }
 }

public void resize(int width, int height) {
   mWidth = width;
   mHeight = height;
   getHolder().setFixedSize(width, height);
   requestLayout();
   invalidate();
 }
}

实例化的时候记得调用resize方法就好了。

注意和camera的预览尺寸比例一致,且宽高记得传正确,不然可能不全屏

来源:https://www.jianshu.com/p/0ea58e77ef57

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com