Андроид:Как создать собственный виджет предварительного просмотра камеры?
-
11-09-2019 - |
Вопрос
Я пытаюсь разработать собственный виджет для предварительного просмотра камеры.Я хотел бы заполнить экран предварительным просмотром камеры и нарисовать над ним несколько кнопок.
Я попытался создать собственный виджет следующим образом:
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class CapturePreview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
Camera mCamera;
CapturePreview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
// TODO: add more exception handling logic here
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
mCamera.stopPreview();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(w, h);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
и изменил файл main.xml следующим образом:
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout">
<dev.video.client.CapturePreview android:id="@+id/capturePreview" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</RelativeLayout>
В классе Activity я попытался связать виджет следующим образом:
private CapturePreview mPreview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setFullscreen();
setContentView(R.layout.main);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//mPreview = new CapturePreview(this);
//setContentView(mPreview);
mPreview = (CapturePreview)this.findViewById(R.id.capturePreview);
}
Каждый раз, когда я пытаюсь отладить приложение, я получаю сообщение об ошибке и не могу понять, что может быть не так.
Я был бы очень признателен за любую помощь в решении этой проблемы.
Спасибо!
Решение
Чтобы это работало, вам необходимо создать следующий конструктор в SurfaceView:
CapturePreview(Context context, AttributeSet attrs)
Как вы, возможно, знаете, конструкторы Java не наследуются от суперкласса, но это конструктор, который Android пытается вызвать, когда вы используете этот компонент в XML-файле (в отличие от программного определения вашего графического интерфейса).Конечно, это не сработает, отсюда и сообщение об ошибке, которое, на мой взгляд, должно быть намного более ясным.
А Набор атрибутов содержит все атрибуты, упомянутые в объявлении XML, поэтому, если у вас есть собственные атрибуты для вашего компонента, вы можете получить и выполнить над ними действия в конструкторе.
Другие советы
Вы можете реализовать onTouchListener() для соответствующего представления.Когда вы нажимаете на поверхность, система Android автоматически перенаправляет вас к методу onTouchListener().