title: Using a ViewPager over a CameraPreview
body: <p>I've been trying to create a Camera Preview that displays a View Pager with several transparent images over the preview. But, I'm getting this error:</p>
  
  <pre><code>05-10 03:31:23.614: E/AndroidRuntime(674): FATAL EXCEPTION: main
  05-10 03:31:23.614: E/AndroidRuntime(674): java.lang.NullPointerException
  05-10 03:31:23.614: E/AndroidRuntime(674):  at com.android.gs1.MainActivity$CameraPreview.surfaceCreated(MainActivity.java:102)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.SurfaceView.updateWindow(SurfaceView.java:562)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.SurfaceView.access$000(SurfaceView.java:82)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:171)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1596)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.os.Handler.dispatchMessage(Handler.java:99)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.os.Looper.loop(Looper.java:137)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at android.app.ActivityThread.main(ActivityThread.java:4340)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at java.lang.reflect.Method.invokeNative(Native Method)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at java.lang.reflect.Method.invoke(Method.java:511)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
  05-10 03:31:23.614: E/AndroidRuntime(674):  at dalvik.system.NativeStart.main(Native Method)
  </code></pre>
  
  <p>Here is my code:</p>
  
  <pre><code>package com.android.gs1;
  
  import java.io.IOException;
  import android.os.Bundle;
  import android.os.Parcelable;
  import android.app.Activity;
  import android.content.Context;
  import android.hardware.Camera;
  import android.support.v4.view.PagerAdapter;
  import android.support.v4.view.ViewPager;
  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.LinearLayout;
  import android.widget.Toast;
  
  
  public class MainActivity extends Activity {
  
  ViewPager vp;
  Camera mCamera;
  SurfaceHolder mHolder;
  static int j;
  private vpAdapter myAdapter;
  CameraPreview preview;
  
  public static void passPageNumber(int i){
      j = i;
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
  
      Toast.makeText(getApplicationContext(), "Swipe Left or Right to Select an Option", Toast.LENGTH_LONG).show();
      vp = (ViewPager) findViewById(R.id.viewpager);
      myAdapter = new vpAdapter();
      preview = new CameraPreview(getApplicationContext(), mCamera);
      ((LinearLayout) findViewById(R.id.preview)).addView(preview);
      vp.setAdapter(myAdapter);
  }
  
  private class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
  
  
      private final String TAG = null;
  
  
      public CameraPreview(Context context, Camera camera) {
          super(context);
          // TODO Auto-generated constructor stub
          mCamera = camera;
  
          // Install a SurfaceHolder.Callback so we get notified when the
          // underlying surface is created and destroyed.
          mHolder = getHolder();
          mHolder.addCallback(this);
  
          // deprecated setting, but required on Android versions prior to 3.0
        //  mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      }
  
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width,
              int height) {
          // TODO Auto-generated method stub
          if (mHolder.getSurface() == null){
                // preview surface does not exist
                return;
              }
  
              // stop preview before making changes
              try {
                 mCamera.stopPreview();
              } catch (Exception e){
                // ignore: tried to stop a non-existent preview
              }
  
              // set preview size and make any resize, rotate or
              // reformatting changes here
  
              // start preview with new settings
              try {
                  mCamera.setPreviewDisplay(mHolder);
                  mCamera.startPreview();
  
              } catch (Exception e){
                  Log.d(TAG, "Error starting camera preview: " + e.getMessage());
              }
      }
  
      @Override
      public void surfaceCreated(SurfaceHolder holder) {
          // TODO Auto-generated method stub
          try {
              mCamera = Camera.open();
              mCamera.setPreviewDisplay(holder);
              mCamera.startPreview();
          } catch (IOException e) {
              Log.d(TAG, "Error setting camera preview: " + e.getMessage());
          }
      }
  
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
          // TODO Auto-generated method stub
  
      }
  
  }
  private class vpAdapter extends PagerAdapter{
  
      @Override
      public int getCount() {
          // TODO Auto-generated method stub
          return 5;
      }
  
      @Override
      public boolean isViewFromObject(View view, Object object) {
          // TODO Auto-generated method stub
          return view == ((LinearLayout)object);
      }
  
      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
          // TODO Auto-generated method stub
          ((ViewPager)container).removeView((LinearLayout)object);
      }
  
      @Override
      public void finishUpdate(ViewGroup container) {
          // TODO Auto-generated method stub
  
      }
  
  
      @Override
      public Object instantiateItem(View container, int position) {
          // TODO Auto-generated method stub
          LayoutInflater inflater = (LayoutInflater)container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          View v = null;
  
          switch(position){
          case 0:
              v = inflater.inflate(R.layout.first, null);
              break;
          case 1:
              v = inflater.inflate(R.layout.second, null);
              break;
          case 2:
              v = inflater.inflate(R.layout.third, null);
              break;
          case 3:
              v = inflater.inflate(R.layout.fourth, null);
              break;
          case 4:
              v = inflater.inflate(R.layout.fifth, null);
              break;
          }
  
  
          ((ViewPager)container).addView(v, 0);
          return v;
      }
      @Override
      public void startUpdate(ViewGroup container) {
          // TODO Auto-generated method stub
  
      }
      @Override
      public Parcelable saveState() {
          // TODO Auto-generated method stub
          return null;
      }
  
  }
  }
  </code></pre>
  
  <p>Here is my xml</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity" 
  android:background="#545454" &gt;
  
  &lt;android.support.v4.view.ViewPager
      android:id="@+android:id/viewpager"
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:layout_weight="0.49" /&gt;
  &lt;LinearLayout
      android:id="@+id/preview"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"&gt;
  &lt;/LinearLayout&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>There are five more xml for the viewpager. All of them look like this, but with different name and ids.</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
   &gt;
  
  &lt;ImageView
  android:id="@+id/image1"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:adjustViewBounds="false"
  android:contentDescription="@string/description_image_1"
  android:scaleType="fitXY"
  android:src="@drawable/first" /&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Thank you very much</p>
  
  <p><strong>Edit: Someone asked me the final working version of my code. Here it is:</strong></p>
  
  <pre><code>public class MainActivity extends Activity {
  
  ViewPager vp;
  vpAdapter myAdapter;
  Camera camera = null;
  SurfaceHolder previewHolder = null;
  private SurfaceView preview = null;
  private boolean inPreview = false;
  private boolean cameraConfigured = false;
  public static String[] arrayURL;
  public static boolean urlsPassed;
  private View mContentView;
  private View mLoadingView;
  
  private int mShortAnimationDuration;
  
  
  @SuppressWarnings("deprecation")
  @SuppressLint("NewApi")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      setContentView(R.layout.activity_main);
      Toast.makeText(getApplicationContext(), "Swipe Left or Right to Select an Option", Toast.LENGTH_SHORT).show();
      //NEW CODE
  
      mContentView = findViewById(R.id.content);
      mLoadingView = findViewById(R.id.loading_spinner);
      mContentView.setVisibility(View.GONE);
      mShortAnimationDuration = getResources().getInteger(
              android.R.integer.config_shortAnimTime);
      //NEW CODE
      preview=(SurfaceView)findViewById(R.id.preview);
      preview.setZOrderOnTop(false);
      previewHolder=preview.getHolder();
      previewHolder.addCallback(surfaceCallback);
      previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  
  }
  private void crossfade() {
  
      // Set the content view to 0% opacity but visible, so that it is visible
      // (but fully transparent) during the animation.
      mContentView.setAlpha(0f);
      mContentView.setVisibility(View.VISIBLE);
  
      // Animate the content view to 100% opacity, and clear any animation
      // listener set on the view.
      mContentView.animate()
              .alpha(1f)
              .setDuration(mShortAnimationDuration)
              .setListener(null);
  
      // Animate the loading view to 0% opacity. After the animation ends,
      // set its visibility to GONE as an optimization step (it won't
      // participate in layout passes, etc.)
      mLoadingView.animate()
              .alpha(0f)
              .setDuration(mShortAnimationDuration)
              .setListener(new AnimatorListenerAdapter() {
                  @Override
                  public void onAnimationEnd(Animator animation) {
                      mLoadingView.setVisibility(View.GONE);
                  }
              });
  }
      public static void assignURL(String[] urls){
      arrayURL = urls;
  }
  
      public static void urlsPassed(boolean transfer){
          urlsPassed = transfer;
      }
  
  @Override
    public void onResume() {
      super.onResume();
      camera=Camera.open();
  }
  
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
   }
  @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&lt;=width &amp;&amp; size.height&lt;=height) {
              if (result==null) {
                  result=size;
              }
              else {
                  int resultArea=result.width*result.height;
                  int newArea=size.width*size.height;
  
                  if (newArea&gt;resultArea) {
                      result=size;
                  }
              }
          }
      }
  
      return(result);
  }
  private void initPreview(int width, int height) {
      if (camera!=null &amp;&amp; previewHolder.getSurface()!=null) {
        try {
          camera.setPreviewDisplay(previewHolder);
        }
        catch (Throwable t) {
          Log.e("PreviewDemo-surfaceCallback",
                "Exception in setPreviewDisplay()", t);
          Toast
            .makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG)
            .show();
        }
  
        if (!cameraConfigured) {
          Camera.Parameters parameters=camera.getParameters();
          Camera.Size size=getBestPreviewSize(width, height,
                                              parameters);
  
          if (size!=null) {
            parameters.setPreviewSize(size.width, size.height);
            camera.setParameters(parameters);
            cameraConfigured=true;
          }
        }
      }
    }
  
   private void startPreview() {
          if (cameraConfigured &amp;&amp; camera!=null) {
            camera.startPreview();
            inPreview=true;
            crossfade();
            if(urlsPassed){
              myAdapter = new vpAdapter(this,  arrayURL);
              vp = (ViewPager) findViewById(R.id.viewpager);
              vp.setAdapter(myAdapter);
              vp.setCurrentItem(0);
            }
          }
        }
  
   SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
            // no-op -- wait until surfaceChanged()
          }
  
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
  
  
            Camera.Parameters parameters = camera.getParameters();
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            camera.setParameters(parameters);
            initPreview(width, height);
            startPreview();
            camera.autoFocus(null);
          }
  
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
            // no-op
          }
        };
  
  }
  </code></pre>