在SurfaceView加载时显示我的布局相机预览
我有一个带有开始按钮的简单屏幕。当按下“开始”按钮时,我想要使用SurfaceView转到新屏幕以显示相机。在SurfaceView加载时显示我的布局相机预览
一切工作正常,但相机需要一段时间才能加载,这给我一个黑屏。 我想要加载新的布局。而不是启动相机后它已被加载中...
为此,我在后台线程全部装入相机了,不过,我得到一个黑色的屏幕... 这里是我的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/blue_bg">
<SurfaceView
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_below="@id/scan_header"
android:layout_above="@id/scan_footer">
</SurfaceView>
</RelativeLayout>
这里是我的活动,它加载新视图的方法:
private void setContent()
{
setContentView(R.layout.scan)
Thread t = new Thread()
{
public void run()
{
final SurfaceView mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera);
final SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder();
try
{
cameraView = new CameraView();
mSurfaceHolder.addCallback(cameraView);
cameraView.setPictureListener(SunpluggedActivity.this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} catch(Exception e)
{
Log.d(TAG, "Another exception");
e.printStackTrace();
}
}
};
t.start();
}
怎么来的,新的布局没有显示,直到线程已经完成加载摄像头?
编辑:我在线程中尝试了Thread.sleep(200)休眠一段时间。当我做到这一点,新的布局immedeately显示,但相机从未开始......
好的,问题是我在xml布局中使用了我的SurfaceView。 你调用的那一刻:setContentView(your_layout) - > XML文件被夸大了。 这意味着,SurfaceView也会膨胀。这又意味着SurfaceView onSurfaceCreated方法被调用,这触发打开相机等。
因此,这整个过程需要一段时间,因此,您以前的活动(例如启动与SurfaceView的活动)似乎没有反应...
我的解决方案,在BG线程中创建CameraView解决了无法响应。但未能在SurfaceView中显示相机输出。
解决方案是从您的XML中删除您的SurfaceView。这会立即开始你的活动(因为SurfaceView &相机没有实例化)。 加载新的“活动”布局后,可以以编程方式将新的SurfaceView添加到屏幕。当然,这也需要花费时间,但是您的UI会快速切换到新的活动,并且您可以在SurfaceView和相机加载的同时显示加载器!
SO:删除SURFACEVIEW从XML - >添加IT编程: 发射活动:
public class Launch extends Activity implements OnClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.button1);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(Launch.this, SurfaceTestActivity.class);
startActivity(intent);
}
}
的main.xml(只需一个按钮,启动新的活动)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff6600">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</RelativeLayout>
这里的第二个活动(其中包含SurfaceView)
public class SurfaceTestActivity extends Activity {
private Context mContext;
private CameraView cameraView;
private Handler mHandler = new Handler();
private final Runnable mLoadCamera = new Runnable()
{
public void run()
{
startCamera();
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContent();
mContext = getApplicationContext();
}
private void startCamera()
{
RelativeLayout rl = (RelativeLayout)findViewById(R.id.surface_camera);
SurfaceView surfaceView = new SurfaceView(mContext);
final SurfaceHolder mSurfaceHolder = surfaceView.getHolder();
try
{
cameraView = new CameraView();
mSurfaceHolder.addCallback(cameraView);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} catch(Exception e)
{
Log.d("debug", "Another exception");
e.printStackTrace();
}
if(rl != null && surfaceView != null)
rl.addView(surfaceView);
}
private void setContent()
{
setContentView(R.layout.scan);
// Post the Runnable with a Slight delay -> than your layout will be
// shown. Without the delay -> your UI will feel inresponsive
mHandler.postDelayed(mLoadCamera, 100);
}
}
这里是t他第二次活动的布局(无SURFACEVIEW)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff6600">
<RelativeLayout
android:id="@+id/header"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt"></TextView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/footer"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt"></TextView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_above="@+id/footer"
android:layout_below="@+id/header"
android:background="#ff0066">
</RelativeLayout>
</RelativeLayout>
最后,完成了答案,这里是为CameraView()的代码。它实际上只是一个简单的实现来打开相机和显示内容:
public class CameraView implements SurfaceHolder.Callback{
// Variables
private Camera mCamera = null;
private boolean mPreviewRunning = false;
private boolean mProcessing = false;
private int mWidth = 0;
private int mHeight = 0;
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
if(mPreviewRunning)
{
mCamera.stopPreview();
}
// Store width and height
mWidth = width;
mHeight = height;
// Set camera parameters
Camera.Parameters p = mCamera.getParameters();
mCamera.setParameters(p);
if(android.os.Build.VERSION.SDK_INT >= 8)
{ // If API >= 8 -> rotate display...
mCamera.setDisplayOrientation(90);
}
try
{
mCamera.setPreviewDisplay(holder);
} catch(IOException e)
{
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
@Override
public void surfaceCreated(final SurfaceHolder holder)
{
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (IOException e)
{
mCamera.release();
mCamera = null;
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
if(mCamera != null)
{
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mPreviewRunning = false;
mCamera.release();
mCamera = null;
}
}
}
Android Developers指南还建议在WorkerThread中调用Camera.open()以避免阻塞UI线程。 –
这段代码工作得非常好......如果我想在其上添加我的布局,该怎么办? –
在xml中,创建一个包含surfaceview的相关布局。这个surfaceView将是你的'相机'视图。最重要的是,你可以添加所有的布局。 – Entreco