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 突然滚动