微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – 在SurfaceView加载Camera Preview时显示我的布局

我有一个带开始按钮的简单屏幕.按下“开始”按钮后,我想转到带有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>

这是我的Activity中的方法,它加载新视图:

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中的Thread.sleep(200)睡了一段时间…当我这样做时,新的布局显示出来,但相机永远不会启动…

解决方法

好吧,问题是我在xml布局中使用了SurfaceView.
你打电话的那一刻:setContentView(your_layout) – > XML文件被夸大了.
这意味着,SurfaceView也会膨胀.这再次意味着调用SurfaceView onSurfaceCreated方法,触发打开相机等.

因此,整个过程需要一段时间,因此,您之前的Activity(例如,使用SurfaceView启动Activity的那个)似乎没有响应……

我在BG线程中创建Cameraview的解决方解决了无响应问题.但未能在SurfaceView中显示Camera输出.

解决方案是从xml中删除SurfaceView.这将立即启动您的活动(因为SurfaceView& Camera未实例化).
加载新的“活动”布局后,可以以编程方式将新的SurfaceView添加到屏幕上.当然,这也需要时间,但您的UI会快速切换到新活动,并且您可以在SurfaceView和Camera加载时显示加载程序!

所以:从XML中删除SURFACEVIEW – >在程序上添加它:
发布活动:

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);
    }
}

这是第二个Activity的布局(没有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;
        }   
    }
}

原文地址:https://www.jb51.cc/android/317425.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐