Android ViewPager,片段中的cameraview未显示

Posted

技术标签:

【中文标题】Android ViewPager,片段中的cameraview未显示【英文标题】:Android ViewPager, cameraview in fragment not showing 【发布时间】:2014-12-25 05:39:46 【问题描述】:

我正在尝试创建一个包含 3 个片段的应用程序,我正在使用 viewpager 浏览它们。 第一个是列表,第二个应该是相机,第三个又是一个列表。 滑动有效,但是当我到达第二个片段时,cameraPreview 是黑色的。 我没有得到崩溃或不同的堆栈跟踪。 我之前创建了这个应用程序的一部分,但没有刷卡,它确实有效。在新应用中再次设置时我没有更改片段,我只是将导入从 android.app.Fragment 更改为 android.support.v4.app.Fragment 。

这个例子是我用来创建应用程序的:ViewPager with multiple Fragments and Layout files - How To 我的还没有那么不同,我要感谢 Haxor 的精彩解释,它真的帮助了我。我还不能投票,所以我会以这种方式感谢你:)

MainActivity.class:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;


public class MainActivity extends FragmentActivity 

LinearLayout ButtonBar;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
    pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));



private class MyPagerAdapter extends FragmentPagerAdapter 

    public MyPagerAdapter(FragmentManager fm) 
        super(fm);
    

    @Override
    public Fragment getItem(int pos) 
        switch(pos) 
            case 0:
                return FirstFragment.newInstance("FirstFragment, Instance 1");
            case 1:
                return SecondFragment.newInstance("SecondFragment, Instance 1");
            case 2:
                return ThirdFragment.newInstance("ThirdFragment, Instance 1");
            default:
                return ThirdFragment.newInstance("ThirdFragment, Default");
        
    

    @Override
    public int getCount() 
        return 3;
    


activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".MainActivity"
android:background="#ffff">

<android.support.v4.view.ViewPager
    android:id="@+id/viewPager"
    android:layout_
    android:layout_/>
</RelativeLayout>

第二个片段.class:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.io.IOException;
import java.io.OutputStream;

/**
 * Created by Gebruiker on 29-10-2014.
 */
public class SecondFragment extends Fragment 

View rootView;
ImageButton cameraShootButton;
ImageButton cameraChangeButton;
Boolean switching = false;
View.OnClickListener tapper = null;
SurfaceView cameraPreview = null;
SurfaceHolder cameraPreviewHolder = null;
Camera camera = null;
boolean inPreview = false;
boolean cameraConfigured = false;
Integer currentCamera;

public static SecondFragment newInstance(String text) 

    SecondFragment f = new SecondFragment();
    Bundle b = new Bundle();
    b.putString("msg", text);

    f.setArguments(b);

    return f;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    rootView = inflater.inflate(R.layout.second_frag, container, false);


    cameraShootButton = (ImageButton) rootView.findViewById(R.id.captureB);
    cameraChangeButton = (ImageButton) rootView.findViewById(R.id.changeCameraB);
    cameraPreview = (SurfaceView) rootView.findViewById(R.id.cameraView);

    cameraPreviewHolder = cameraPreview.getHolder();
    cameraPreviewHolder.addCallback(surfaceCallback);
    cameraPreviewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    tapper = new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            if (v.getId() == R.id.captureB) 
                camera.takePicture(ShutterCallback, PictureCallbackRaw, null, PictureCallbackJpeg);
             else if (v.getId() == R.id.changeCameraB) 
                if (switching == true)
                    return;
                
                changeCamera();
            
        
    ;

    cameraShootButton.setOnClickListener(tapper);
    cameraChangeButton.setOnClickListener(tapper);
    return rootView;


@Override
public void onResume() 
    super.onResume();
    camera = getCamera("back");
    currentCamera = 1;
    startPreview();


@Override
public void onPause() 
    if (inPreview) 
        camera.stopPreview();
    
    camera.release();
    camera = null;
    inPreview = false;

    super.onPause();


private Camera.Size getBestPreviewSize(int width, int height,
                                       Camera.Parameters parameters) 
    Camera.Size result = null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) 
        if (size.width <= width && size.height <= height) 
            if (result == null) 
                result = size;
             else 
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;

                if (newArea > resultArea) 
                    result = size;
                
            
        
    

    return (result);


private void initPreview(int width, int height) 
    if (camera != null && cameraPreviewHolder.getSurface() != null) 
        try 
            camera.setPreviewDisplay(cameraPreviewHolder);
         catch (Throwable t) 
            Log.e("PreviewDemo-surfaceCallback",
                    "Exception in setPreviewDisplay()", t);
        

        if (!cameraConfigured) 
            Camera.Parameters parameters = camera.getParameters();
            Log.v("CAMERA", parameters.toString());
            Camera.Size size = getBestPreviewSize(width, height,
                    parameters);

            if (size != null) 
                Log.v("CameraPreviewHeight", ""+cameraPreview.getMeasuredHeight());
                Log.v("CameraRES", size.width + " " + size.height);
                parameters.setPreviewSize(size.width, size.height);
                camera.setParameters(parameters);
                cameraConfigured = true;
            
        
    


private void startPreview() 
    if (cameraConfigured && camera != null) 
        camera.startPreview();
        inPreview = true;
        camera.setDisplayOrientation(90);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 
            camera.enableShutterSound(false);
        
    


private void changeCamera() 
    switching = true;
    if (inPreview) 
        camera.stopPreview();
        camera.setPreviewCallback(null);
    
    camera.release();
    camera = null;
    inPreview = false;
    if (currentCamera==1)
        camera = getCamera("front");
        currentCamera =2;
    
    else
        camera = getCamera("back");
        currentCamera = 1;
    
    camera.setDisplayOrientation(90);
    try 
        camera.setPreviewDisplay(cameraPreviewHolder);
        cameraPreviewHolder.addCallback(surfaceCallback);
        camera.startPreview();
     catch (IOException e) 
        e.printStackTrace();
    

    inPreview = true;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 
        camera.enableShutterSound(false);
    
    switching = false;



SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() 
    public void surfaceCreated(SurfaceHolder holder) 
        // no-op -- wait until surfaceChanged()
    

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) 
        initPreview(width, height);
        startPreview();
    

    public void surfaceDestroyed(SurfaceHolder holder) 
        // no-op
    
;

Camera.ShutterCallback ShutterCallback = new Camera.ShutterCallback() 
    public void surfaceCreated(SurfaceHolder holder) 
        // no-op -- wait until surfaceChanged()
    

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) 
        initPreview(width, height);
        startPreview();
    

    public void surfaceDestroyed(SurfaceHolder holder) 
        // no-op
    

    @Override
    public void onShutter() 

    
;

Camera.PictureCallback PictureCallbackRaw = new Camera.PictureCallback() 
    public void surfaceCreated(SurfaceHolder holder) 
        // no-op -- wait until surfaceChanged()
    

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) 
        initPreview(width, height);
        startPreview();
    

    public void surfaceDestroyed(SurfaceHolder holder) 
        // no-op
    

    @Override
    public void onPictureTaken(byte[] data, Camera camera) 

    
;

Camera.PictureCallback PictureCallbackJpeg = new Camera.PictureCallback() 
    public void surfaceCreated(SurfaceHolder holder) 
        // no-op -- wait until surfaceChanged()
    

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) 
        initPreview(width, height);
        startPreview();
    

    public void surfaceDestroyed(SurfaceHolder holder) 
        // no-op
    

    @Override
    public void onPictureTaken(byte[] byteData, Camera camera) 
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 5;
        OutputStream bos = null;
        Bitmap m = BitmapFactory.decodeByteArray(byteData, 0, byteData.length, options);

        //m.compress(Bitmap.CompressFormat.PNG, 75, bos);
        //Log.v("CAPTURED", ""+bos);
    
;

private Camera getCamera(String getCamera) 
    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) 
        Camera.getCameraInfo(camIdx, cameraInfo);
        if ((cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) && (getCamera == "front")) 
            try 
                cam = Camera.open(camIdx);
             catch (RuntimeException e) 
                Log.e("TEST", "Camera failed to open: " + e.getLocalizedMessage());
            
        
        else if ((cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) && (getCamera == "back")) 
            try 
                cam = Camera.open(camIdx);
             catch (RuntimeException e) 
                Log.e("TEST", "Camera failed to open: " + e.getLocalizedMessage());
            
        
    
    return cam;




second_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>

<android.view.SurfaceView
    android:id="@+id/cameraView"
    android:layout_
    android:layout_ />

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="horizontal"
    android:layout_alignParentBottom="true">

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:gravity="center">

        <ImageButton
            android:id="@+id/flitserB"
            android:layout_
            android:layout_
            android:scaleType="fitCenter"
            android:src="@drawable/flash"
            android:background="@null"/>
    </LinearLayout>

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:gravity="center">
        <ImageButton
            android:id="@+id/captureB"
            android:layout_
            android:layout_
            android:scaleType="fitCenter"
            android:src="@drawable/camerashoot"
            android:background="@null"/>
    </LinearLayout>

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:gravity="center">
        <ImageButton
            android:id="@+id/changeCameraB"
            android:layout_
            android:layout_
            android:scaleType="fitCenter"
            android:src="@drawable/camerachange"
            android:background="@null"/>

    </LinearLayout>

</LinearLayout>


</RelativeLayout>

【问题讨论】:

它可以在 viewpager 之外工作吗? 【参考方案1】:

可能你忘了给 AndroidManifest.xml 添加相机权限:

<uses-permission android:name="android.permission.CAMERA" />

参见: http://developer.android.com/reference/android/hardware/Camera.html

【讨论】:

我真的可以把自己拍在我的头上,这是我的问题,我已经搜索了 2 个小时......感谢大家回复和查看我的帖子

以上是关于Android ViewPager,片段中的cameraview未显示的主要内容,如果未能解决你的问题,请参考以下文章

viewpager 中的 3 个 android 片段,如何让它们全部存活?

在 CoordinatorLayout Android 中的 ViewPager 片段中使用 NestedScrollView 突然滚动

Android:导航抽屉片段内的Viewpager

从ViewPager android替换片段

Android使用片段在viewpager中的页面滚动上放置动画

Android:使用Tab检测单个片段viewpager