Yes, of course it is possible. Note that SurfaceView and its associated Surface are two different things, and each can / should be assigned a size.
Surface is the actual memory buffer that will hold the output of the camera, and thus its size determines the size of the actual image that you will receive from each frame. For each format available from the camera, there is a small set of possible (exact) sizes that you can make for this buffer.
SurfaceView is what this image displays when it is available, and can be basically any size in your layout. It will stretch its underlying linked image data to fit all of its layout sizes, but note that the size of this screen is different from the size of the data. Android will automatically resize image data to display. This is what probably causes your sprain.
For example, you can make an autofit based on a SurfaceView View, similar to camera2basic AutoFitTextureView, as follows (this is what I use):
import android.content.Context; import android.util.AttributeSet; import android.view.SurfaceView; public class AutoFitSurfaceView extends SurfaceView { private int mRatioWidth = 0; private int mRatioHeight = 0; public AutoFitSurfaceView(Context context) { this(context, null); } public AutoFitSurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setAspectRatio(int width, int height) { if (width < 0 || height < 0) { throw new IllegalArgumentException("Size cannot be negative."); } mRatioWidth = width; mRatioHeight = height; requestLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension(width, height); } else { if (width < height * mRatioWidth / mRatioHeight) { setMeasuredDimension(width, width * mRatioHeight / mRatioWidth); } else { setMeasuredDimension(height * mRatioWidth / mRatioHeight, height); } } } }
source share