I have been working on LenX for few weeks now, and as it is a camera app, it was necessary to add some type of focus. We decided to add touch based focus. Wherever user touches the screen, Android camera would try to focus in that area.
To start off, I didn’t want to show anything in the SurfaceView except Camera Preview feed. So to indicate the touch focus area, I created a transparent View and put it over SurfaceView.
Instead of beating around the bush, I’d just directly get on to the main point.
AutoFocusCallback and touchFocus method
In CameraPreview class,
This is how Touch based focus works. You provide the camera a list of Camera.Area where you want the camera to focus and set the params. You need to call the AutoFoucsCallback and cancel it to set the focus.
In PreviewSurfaceView where I record the touch and call doTouchFocus with appropriate Rect.
In onTouchEvent, once we get the x and y coordinates of the screen where the user touched, we define a square area of 200px x 200px as (x, y) set as the center. Once we have this Rect, we need to convert it to the Rect which compatible with Camera.
The Camera.Area object contains two data parameters: A Rect object for specifying an area within the camera’s field of view and a weight value, which tells the camera what level of importance this area should be given in light metering or focus calculations.
The Rect field in a Camera.Area object describes a rectangular shape mapped on a 2000 x 2000 unit grid. The coordinates -1000, -1000 represent the top, left corner of the camera image, and coordinates 1000, 1000 represent the bottom, right corner of the camera image
Hence we need to convert the current Rect and interpolate if for -1000 to +1000.
Once this is done, we need to show the focus indication else users don’t think anything happened. So I added a View where I draw a rectangle for 1000 msec and then hide it. I created a Handler and call postDelayed method with 1000 msec and pass an empty Rect to drawingView. And call invalidate() so that its onDraw method is called.
So, this was how I put Touch to Focus in LenX. The project code is up on GitHub. You can fork it from here.