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
投稿
猜你喜欢
- 一、插入排序算法实现java版本public static int[] insert_sort(int[] a){for (int i =
- 一、任务和执行策略之间的隐性耦合Executor可以将任务的提交和任务的执行策略解耦只有任务是同类型的且执行时间差别不大,才能发挥最大性能,
- 1. 初始 Spring Boot1.1 什么是Spring BootSpring 的诞生是为了简化 Java 程序的开发的Spring B
- 带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码。生成的二
- ArrayList和LinkedList区别、扩容机制及底层实现ArrayListArrayList的底层实现为数组存储在内存中,线程不同步
- 如何查看 Java 的字节码文件?在 Java 中,字节码文件.class实际上是二进制文件,并不能直接查看。要想查看,我们只能通过反编译对
- 简单来说抽象类通常用来作为一个类族的最顶端的父类,用最底层的类表示现实中的具体事物,用最顶层的类表示该类族所有事物的共性。用abstract
- 在一般性开发中,笔者经常看到很多同学在对待java并发开发模型中只会使用一些基础的方法。比如Volatile,synchronized。像L
- 项目结构项目路径可以自己定义,只要路径映射正确就可以pom.xml <properties> <spring.versio
- 本文实例分析了C#中结构(struct)的部分初始化和完全初始化,分享给大家供大家参考。具体分析如下:假设有这样一个值类型struct,如下
- 一、案例场景在使用 @Autowired 时,你或多或少都会遇过类似的错误:required a single bean, but 2 we
- 如下所示:package com.lstc.test;public class TestDemo3 {String str = new St
- 到底什么是反射呢???反射的核心就是JVM在运行时才动态加载类或调用方法,访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。每
- 包含默认敏感词过滤和自定义敏感词过滤。导入依赖<dependency> <groupId>com.git
- 本文实例讲述了在类库或winform项目中打开另一个winform项目窗体的方法。分享给大家供大家参考。具体如下:一、问题:假设类库或win
- 一、显式锁什么是显式锁?由自己手动获取锁,然后手动释放的锁。有了 synchronized(内置锁) 为什么还要 Lock(显示锁)?使用
- 延迟加载1 使用延迟加载意义在进行数据查询时,为了提高数据库查询性能,尽量使用单表查询,因为单表查询比多表关联查询速度要快。如果查询单表就可
- 一、ArrayList是什么ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元
- 输入一个数组,然后颠倒次序进行输出,这种算法在程序开发
- 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。示例 1:输入: 1->1->2输出: 1->2示例 2:输