在屏幕的一部分上使用带有摄像头的 android.view.SurfaceView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2485141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using android.view.SurfaceView with a camera on part of the screen
提问by oneself
I trying to put together an Android app that will take a picture and process it in some way. I'd like the layout to be similar to Google Goggles. Meaning, camera preview on the top, and some controls on the bottom using portrait orientation.
我试图组合一个 Android 应用程序,它将拍照并以某种方式处理它。我希望布局类似于 Google Goggles。意思是,顶部的相机预览,底部的一些控件使用纵向。
I've built a first version using code sample from here. This works, but I want to add a button on the bottom.
我已经使用这里的代码示例构建了第一个版本。这有效,但我想在底部添加一个按钮。
I've modified my main.xml to look as follows (based on comments from this post):
我已将 main.xml 修改为如下所示(基于这篇文章的评论):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.view.SurfaceView android:id="@+id/preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true" />
<Button android:id="@+id/snap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Snap"
android:layout_alignParentBottom="true" />
</RelativeLayout>
But when I run this code I get the following exception:
但是当我运行此代码时,出现以下异常:
E/AndroidRuntime( 199): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 199): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.beerometer/com.beerometer.ImageCapture}: android.view.InflateException: Binary XML file line #6: Error inflating class Android.view.SurfaceView
E/AndroidRuntime( 199): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
E/AndroidRuntime( 199): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
E/AndroidRuntime( 199): at android.app.ActivityThread.access00(ActivityThread.java:119)
E/AndroidRuntime( 199): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
E/AndroidRuntime( 199): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 199): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 199): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 199): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 199): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 199): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 199): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 199): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 199): Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class Android.view.SurfaceView
E/AndroidRuntime( 199): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:576)
E/AndroidRuntime( 199): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
E/AndroidRuntime( 199): at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
E/AndroidRuntime( 199): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
E/AndroidRuntime( 199): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
E/AndroidRuntime( 199): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
E/AndroidRuntime( 199): at android.app.Activity.setContentView(Activity.java:1622)
E/AndroidRuntime( 199): at com.beerometer.ImageCapture.onCreate(ImageCapture.java:37)
E/AndroidRuntime( 199): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 199): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
E/AndroidRuntime( 199): ... 11 more
E/AndroidRuntime( 199): Caused by: java.lang.ClassNotFoundException: Android.view.SurfaceView in loader dalvik.system.PathClassLoader@44bfc7b0
E/AndroidRuntime( 199): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
E/AndroidRuntime( 199): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
E/AndroidRuntime( 199): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
E/AndroidRuntime( 199): at android.view.LayoutInflater.createView(LayoutInflater.java:466)
E/AndroidRuntime( 199): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:565)
E/AndroidRuntime( 199): ... 20 more
When I replace the SurfaceView above with something else, e.g. a TextView, that it displays, but in landscape.
当我用其他东西(例如 TextView)替换上面的 SurfaceView 时,它显示,但在横向。
How can I get a camera preview on part of the screen using portrait view?
如何使用纵向视图在屏幕的一部分上获得相机预览?
Thanks
谢谢
回答by CommonsWare
First, your layout probably won't give you what you want. Consider using a RelativeLayout
, with the Button
anchored to the bottom, and the SurfaceView
anchored to the top of the screen and the top of the Button
.
首先,你的布局可能不会给你你想要的。考虑使用RelativeLayout
,Button
锚定到底部,SurfaceView
锚定到屏幕顶部和Button
.
Also, you have a duplicate xmlns:android="http://schemas.android.com/apk/res/android"
on your SurfaceView
that you don't need. The one on your root element will suffice.
此外,你必须重复xmlns:android="http://schemas.android.com/apk/res/android"
你的SurfaceView
,你不需要。根元素上的一个就足够了。
In terms of your exception, there may be more detail in your stack trace that you are missing, explaining why startPreview()
failed. Look for a "Caused by" or other line mid-way through the stack trace. If you can't identify it, edit your question and paste in the entire stack trace (and ping me via a comment on this answer, since I won't know about the edit otherwise).
就您的异常而言,您的堆栈跟踪中可能有更多您遗漏的细节,解释了startPreview()
失败的原因。在堆栈跟踪的中间寻找“Caused by”或其他行。如果您无法识别它,请编辑您的问题并粘贴到整个堆栈跟踪中(并通过对此答案的评论来 ping 我,因为否则我将不知道该编辑)。
You might also experiment with this book exampleas another Camera
preview app, to see if there's something about how I approach the problem that works better for your circumstance.
您还可以将本书示例作为另一个Camera
预览应用程序进行试验,看看我如何解决更适合您的情况的问题。
回答by Alex Cohn
If I am not missing something, you cannot just use SurfaceView as is. You need a derived class of your own. I usually create this view programmatically, and give it the full screen. But you can cover parts of it with other views, including buttons:
如果我没有遗漏某些东西,您就不能按原样使用 SurfaceView。你需要一个你自己的派生类。我通常以编程方式创建此视图,并为其提供全屏显示。但是你可以用其他视图覆盖它的一部分,包括按钮:
setContentView(new CameraView());
View mainscreen = getLayoutInflater().inflate(R.layout.mainscreen, null, false);
ViewGroup.LayoutParams generalLayoutParam = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
addContentView(mainscreen, generalLayoutParam);
回答by hcpl
Yes you can use a surfaceView. From the surfaceView you can get the SurfaceHolder which then can be used to set the camera's previewDisplay.
是的,您可以使用surfaceView。从surfaceView你可以得到SurfaceHolder,然后它可以用来设置相机的previewDisplay。
SurfaceView preview = (SurfaceView) findViewById(R.id.cameraPreview);
SurfaceHolder previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
You'll need to implement the SurfaceHolder.Callback method in order to update the preview size properly. In surfaceCreated set the previewDisplay of the camera. On surfaceChanged update the previewSize for the camera.
您需要实现 SurfaceHolder.Callback 方法才能正确更新预览大小。在surfaceCreated中设置相机的previewDisplay。在 SurfaceChanged 上更新相机的 previewSize。
camera.setPreviewDisplay(previewHolder);
In fact the example mentioned beforeis a very good reference!
其实前面提到的例子是很好的参考!