title: Surfaceholder.addCallback Not Working; surfaceCreated, surfaceChanged, and surfaceDestroyed Never Being Called
body: <p>I am implementing a camera preview using Scala based on the code in <code>com.example.android.apis.graphics.CameraPreview</code> in Android ApiDemos.  However, the methods of <code>SurfaceHolder.Callback</code> (<code>surfaceCreated</code>, <code>surfaceChanged</code>, and <code>surfaceDestroyed</code>) seem never being called.  Here is the code:</p>
  
  <pre class="lang-scala prettyprint-override"><code>class TakePictureActivity extends ActivityWithLog {
    lazy val preview = findViewById(R.id.preview).asInstanceOf[CameraPreview]
  
    override def onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.take_picture)
    }
  
    override def onResume {
      super.onResume()
      preview.camera = Camera.open()
    }
  
    override def onPause {
      super.onPause()
      for (c &lt;- Option(preview.camera)) {
        c.release()
        preview.camera = null
      }
    }
  }
  
  class CameraPreview(context:  Context,
                      attrs:    AttributeSet,
                      defStyle: Int)
      extends ViewGroup(context, attrs, defStyle)
      with SurfaceHolder.Callback
      with LogTag {
    def this(context: Context, attrs: AttributeSet) = this(context, attrs, 0)
    def this(context: Context) = this(context, null)
  
    private var maybeCamera: Option[Camera] = None
  
    def camera = maybeCamera.getOrElse(null)
  
    def camera_=(c: Camera) {
      maybeCamera = Option(c)
      if (maybeCamera.nonEmpty) requestLayout()
    }
  
    private var previewSize: Option[Camera#Size] = None
  
    def optimalPreviewSize(sizes: Seq[Camera#Size],
                           targetWidth: Int, targetHeight: Int) = {
      val targetRatio = targetWidth.asInstanceOf[Double] / targetHeight
      val targetArea  = targetWidth * targetHeight
      def closestInArea(sizes: Seq[Camera#Size]) =
        sizes.minBy(s =&gt; abs(s.width * s.height - targetArea))
      sizes.filter { size =&gt;
        val r = size.width.asInstanceOf[Double] / size.height
        abs(r - targetRatio) &lt; 0.1
      } match {
        case Seq() =&gt; closestInArea(sizes)
        case xs    =&gt; closestInArea(xs)
      }
    }
  
    override def onMeasure(widthMeasureSpec: Int,
                           heightMeasureSpec: Int) {
      val w = View.resolveSize(getSuggestedMinimumWidth, widthMeasureSpec)
      val h = View.resolveSize(getSuggestedMinimumHeight, heightMeasureSpec)
      setMeasuredDimension(w, h)
      for (c &lt;- maybeCamera) {
        val sizes = c.getParameters.getSupportedPreviewSizes.asScala
        previewSize = Some(optimalPreviewSize(sizes, w, h))
      }
    }
  
    override def onLayout(changed: Boolean,
                          l: Int, t: Int, r: Int, b: Int) {
      if (changed &amp;&amp; getChildCount &gt; 0) {
        val child = getChildAt(0)
        val (w, h) = (r - l, b - t)
        val (pw, ph) = previewSize match {
          case Some(s) =&gt; (s.width, s.height)
          case None    =&gt; (w, h)
        }
        if (w * ph &gt; h * pw) {
          val scaledChildWidth = pw * h / ph
          child.layout((w - scaledChildWidth) / 2, 0,
                       (w + scaledChildWidth) / 2, h)
        } else {
          val scaledChildHeight = ph * w / pw
          child.layout(0, (h - scaledChildHeight) / 2,
                       w, (h - scaledChildHeight) / 2)
        }
      }
    }
  
    val surfaceView = new SurfaceView(context)
    addView(surfaceView)
    surfaceView.getHolder.addCallback(this)
  
    def surfaceCreated(holder: SurfaceHolder) {
      Log.d(TAG, "surfaceCreated")
      for (c &lt;- maybeCamera) c.setPreviewDisplay(holder)
    }
  
    def surfaceChanged(holder: SurfaceHolder,
                       format: Int, width: Int, height: Int) {
      Log.d(TAG, "surfaceChanged")
      for (camera  &lt;- maybeCamera;
           preSize &lt;- previewSize) {
        val params = camera.getParameters
        params.setPreviewSize(preSize.width, preSize.height)
        Log.d(TAG, s"setPreviewSize: ${preSize.width}x${preSize.height}")
        requestLayout()
        camera.setParameters(params)
        camera.startPreview()
      }
    }
  
    def surfaceDestroyed(holder: SurfaceHolder) {
      Log.d(TAG, "surfaceDestroyed")
      for (c &lt;- maybeCamera) c.stopPreview()
    }
  }
  </code></pre>
  
  <p>and layout:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"&gt;
    &lt;CameraPreview android:id="@+id/preview"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent" /&gt;
    &lt;Button android:text="Capture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" /&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Can anyone help me solve this problem?  Thanks!</p>