내 레이아웃 코드.Xamarin.Android에서 표면 뷰 높이를 변경하는 방법은 무엇입니까?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:showIn="@layout/Main">
<LinearLayout
android:id="@+id/camera_ll"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:weightSum="100"
android:orientation="vertical">
<FrameLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="@+id/frameLayout"
android:layout_weight="90" />
<Button
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="@+id/btn_capture"
android:text="Scan Answer Sheet"
fontPath="Fonts/Verb-Semibold.otf"
android:textColor="@android:color/white"
android:background="@drawable/bttn_green"
android:layout_weight="10" />
</LinearLayout>
</RelativeLayout>
내 Java 코드입니다.
public class CameraPreview : Activity, Android.Hardware.Camera.IPictureCallback, Android.Hardware.Camera.IPreviewCallback, Android.Hardware.Camera.IShutterCallback
{
String PICTURE_FILENAME = "picture.jpg";
Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
// The first rear facing camera
int defaultCameraId;
FrameLayout frameLayout;
Button btn_capture;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Hide the window title and go fullscreen.
RequestWindowFeature(WindowFeatures.NoTitle);
Window.AddFlags(WindowManagerFlags.Fullscreen);
// Create our Preview view and set it as the content of our activity.
SetContentView(Resource.Layout.CameraPriview);
frameLayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
btn_capture = FindViewById<Button>(Resource.Id.btn_capture);
mPreview = new Preview(this, frameLayout);
frameLayout.AddView(mPreview);
btn_capture.Click += TakeAPicture;
// Find the total number of cameras available
numberOfCameras = Camera.NumberOfCameras;
// Find the ID of the default camera
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++)
{
Camera.GetCameraInfo(i, cameraInfo);
if (cameraInfo.Facing == CameraFacing.Back)
{
defaultCameraId = i;
}
}
}
private void TakeAPicture(object sender, EventArgs eventArgs)
{
Android.Hardware.Camera.Parameters p = mCamera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
mCamera.SetParameters(p);
mCamera.TakePicture(this, this, this);
}
void Camera.IPictureCallback.OnPictureTaken(byte[] data, Android.Hardware.Camera camera)
{
FileOutputStream outStream = null;
File dataDir = Android.OS.Environment.ExternalStorageDirectory;
if (data != null)
{
try
{
outStream = new FileOutputStream(dataDir + "/" + PICTURE_FILENAME);
outStream.Write(data);
outStream.Close();
}
catch (FileNotFoundException e)
{
System.Console.Out.WriteLine(e.Message);
}
catch (IOException ie)
{
System.Console.Out.WriteLine(ie.Message);
}
}
}
void Camera.IPreviewCallback.OnPreviewFrame(byte[] b, Android.Hardware.Camera c)
{
}
void Camera.IShutterCallback.OnShutter()
{
}
protected override void OnResume()
{
base.OnResume();
// Open the default i.e. the first rear facing camera.
mCamera = Camera.Open();
cameraCurrentlyLocked = defaultCameraId;
mPreview.PreviewCamera = mCamera;
mCamera.SetDisplayOrientation(90);
}
protected override void OnPause()
{
base.OnPause();
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null)
{
mPreview.PreviewCamera = null;
mCamera.Release();
mCamera = null;
}
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
// Inflate our menu which can gather user input for switching camera
//MenuInflater.Inflate(Resource.Menu.camera_menu, menu);
return true;
}
}
표면보기 코드.
class Preview : ViewGroup, ISurfaceHolderCallback
{
string TAG = "Preview";
FrameLayout f;
SurfaceView mSurfaceView;
ISurfaceHolder mHolder;
Camera.Size mPreviewSize;
IList<Camera.Size> mSupportedPreviewSizes;
Camera _camera;
public Camera PreviewCamera
{
get { return _camera; }
set
{
_camera = value;
if (_camera != null)
{
mSupportedPreviewSizes = PreviewCamera.GetParameters().SupportedPreviewSizes;
RequestLayout();
}
}
}
public Preview(Context context, FrameLayout f) : base(context)
{
this.f = f;
mSurfaceView = new SurfaceView(context);
AddView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.Holder;
mHolder.AddCallback(this);
mHolder.SetType(SurfaceType.PushBuffers);
}
public void SwitchCamera(Camera camera)
{
PreviewCamera = camera;
try
{
camera.SetPreviewDisplay(mHolder);
}
catch (Java.IO.IOException exception)
{
Log.Error(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.GetParameters();
parameters.SetPreviewSize(mPreviewSize.Width, mPreviewSize.Height);
RequestLayout();
camera.SetParameters(parameters);
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
int width = ResolveSize(SuggestedMinimumWidth, widthMeasureSpec);
int height = ResolveSize(SuggestedMinimumHeight, heightMeasureSpec);
SetMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null)
{
mPreviewSize = GetOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
if (changed && ChildCount > 0)
{
View child = GetChildAt(0);
int width = r - l;
int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null)
{
previewWidth = mPreviewSize.Width;
previewHeight = mPreviewSize.Height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth)
{
int scaledChildWidth = previewWidth * height/previewHeight;
child.Layout((width - scaledChildWidth)/2, 0,
(width + scaledChildWidth)/2, height);
}
else
{
int scaledChildHeight = previewHeight * width/previewWidth;
child.Layout(0, (height - scaledChildHeight)/2,
width, (height + scaledChildHeight)/2);
}
}
}
public void SurfaceCreated(ISurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where
// to draw.
try
{
if (PreviewCamera != null)
{
PreviewCamera.SetPreviewDisplay(holder);
}
}
catch (Java.IO.IOException exception)
{
Log.Error(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
// Surface will be destroyed when we return, so stop the preview.
if (PreviewCamera != null)
{
PreviewCamera.StopPreview();
}
}
private Camera.Size GetOptimalPreviewSize(IList<Camera.Size> sizes, int w, int h)
{
const double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double)w/h;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MaxValue;
int targetHeight = h;
// Try to find an size match aspect ratio and size
foreach (Camera.Size size in sizes)
{
double ratio = (double)size.Width/size.Height;
if (Math.Abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.Abs(size.Height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.Abs(size.Height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null)
{
minDiff = Double.MaxValue;
foreach (Camera.Size size in sizes)
{
if (Math.Abs(size.Height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.Abs(size.Height - targetHeight);
}
}
}
return optimalSize;
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int w, int h)
{
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = PreviewCamera.GetParameters();
parameters.SetPreviewSize(mPreviewSize.Width, mPreviewSize.Height);
RequestLayout();
PreviewCamera.SetParameters(parameters);
PreviewCamera.StartPreview();
}
}
출력 :
지금 내가 나를 위해 일하는 모든 사용 가능한 공간만을 채우기 위해 카메라의 높이를 증가합니다. 누구든지 솔루션을 알면 감사합니다.
어떤 Android API 수준을 타겟팅하고 있습니까? –
KitKat (4.4.4)에서 테스트 중이며 최신 –