Android SurfaceView预览变形完美解决方法
作者:KingVic 时间:2021-11-14 10:29:22
这个问题百度上一搜一大把,基本上都是说找到和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
标签:android,预览,变形
0
投稿
猜你喜欢
spring boot微服务场景下apollo加载过程解析
2022-05-20 13:55:32
WinForm中KeyDown,KeyPress和KeyUp的顺序与区别解析
2023-06-30 22:34:36
Android中ADB命令用法大结局
2022-12-18 10:36:28
Android仿微信语音对讲录音功能
2021-10-12 22:13:36
C#实现SMTP邮件附件发送功能详解
2022-08-14 10:09:38
springMVC+ajax实现文件上传且带进度条实例
2022-01-15 16:42:36
c#使用S22.Imap收剑灵激活码邮件代码示例(imap收邮件)
2022-11-27 20:59:37
Android仿iPhone日期时间选择器详解
2023-09-11 04:23:37
Android实现自定义曲线图
2023-08-22 07:05:01
Spring Security+JWT简述(附源码)
2022-10-16 11:57:51
Java数据结构学习之树
2022-01-19 23:40:58
简单了解Java多态向上转型相关原理
2023-10-11 16:11:01
Android使用音频信息绘制动态波纹
2022-11-05 00:51:50
Java实现TFIDF算法代码分享
2023-12-23 20:54:45
详解C#使用AD(Active Directory)验证内网用户名密码
2023-03-03 23:17:47
Spring Security认证机制源码层探究
2022-07-27 19:05:26
Java序列化与反序列化的实例分析讲解
2022-09-16 05:58:39
Java中的装箱和拆箱深入理解
2023-02-22 08:18:10
Java使用DateTimeFormatter格式化输入的日期时间
2023-03-09 04:52:38
Android控件实现水滴效果
2021-07-31 20:43:51