首页 > 系统 > Android > 正文

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

2019-10-22 18:13:04
字体:
来源:转载
供稿:网友

这个问题百度上一搜一大把,基本上都是说找到和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的预览尺寸比例一致,且宽高记得传正确,不然可能不全屏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表