2015-08-06 7 views
2

Я создал расширенный класс SurfaceView для предварительного просмотра камеры.Как вы используете расширенный класс в XML-макете?

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    SurfaceHolder mHolder; 
    Camera mCamera; 

    CameraPreview(Context context) { 
     super(context); 

     mHolder = this.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. 
     try { 
      mCamera = Camera.open(); 
      mCamera.setPreviewDisplay(holder); 
     } catch (Exception e){ 
      Log.wtf("surfaceCreated", e.toString()); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     try { 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } catch (Exception e){ 
      Log.wtf("surfaceDestroyed", e.toString()); 
     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     try { 
      Camera.Parameters parameters = mCamera.getParameters(); 
      // parameters.setPreviewSize(w, h); 
      // parameters.setPreviewSize(222, 222); 
      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } catch (Exception e){ 
      Log.wtf("surfaceChanged", e.toString()); 
     } 
    } 
} 

Он работает как полноэкранный предварительный просмотр при использовании в деятельности, как это:

public class CameraActivity extends Activity { 
    CameraPreview mPreview; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     mPreview = new CameraPreview(this); 
     setContentView(mPreview); 
    } 
} 

Когда я пытаюсь использовать его в макет XML файл, он дает ClassNotFoundException.

<CameraPreview class="com.xxxxxx.camera3.CameraPreview" 
    android:layout_width="260dp" 
    android:layout_height="260dp" 
    android:id="@+id/surfaceView" 
    android:background="#ff404040" 
    android:layout_gravity="center_horizontal"/> 

Что нужно сделать, чтобы заставить его работать? Как я могу поместить предварительный просмотр камеры в SurfaceView?

ответ

5

Произнесите пакет, который содержит новый вид называется: com.ranandar.views

В вашем XML выполните следующие действия:

<com.ranandar.views.CameraPreview 
    android:layout_width="260dp" 
    android:layout_height="260dp" 
    android:id="@+id/surfaceView" 
    android:background="#ff404040" 
    android:layout_gravity="center_horizontal"/> 

Это выглядит в пакете com.ranandar. views, находит класс, который определяет это представление, и использует его.

Существует проблема, хотя в вашей деятельности. Вы настроите представление содержимого просто на то, что вид сверху, это неправильно.

EDIT: добавление примера, который вы запросили.

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    SurfaceHolder mHolder; 
    Camera mCamera; 

    CameraPreview(Context context) { 
     super(context); 
     init(); 
    } 

    CameraPreview(Context context, AttributeSet attrs){ 
     super(context, attrs); 
     init(); 
    } 

    public void init(){ 
     mHolder = this.getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    //additionally with all your other code 
    ... 
} 

Так что я сделал добавленный конструктор, необходимый для определения пользовательского представления и использования его в XML. Вам нужно определить дополнительный конструктор, так что, когда вы используете его в XML, набор атрибутов передается в представление. Набор атрибутов - это различные поля, которые вы указали как layout_width/height, background и т. Д. В противном случае без этого конструктора CameraPreview не может быть завышен из-за передачи атрибута, установленного без конструктора для его обработки. Вызов в двухпараметрическом конструкторе super (context, attrs) обрабатывается с использованием определенных вами атрибутов.

Документация вам может понадобиться для дальнейшего обучения: Creating Custom Views

нужно сделать вид корневой для вашего XML файла класса ViewGroup, как RelativeLayout, LinearLayout и т.д ... В этом случае сделать макет кадра:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    andorid:layout_height="match_parent"> 

    <com.ranandar.views.CameraPreview 
     android:id="@+id/camera_preview" 
     android:layout_width="260dp" 
     android:layout_height="260dp" 
     android:id="@+id/surfaceView" 
     android:background="#ff404040" 
     android:layout_gravity="center_horizontal"/> 

</FrameLayout> 

Скажите это XML-файл называется activity_main.xml

сделать следующее:

public class CameraActivity extends Activity { 
    CameraPreview mPreview; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     mPreview = (CameraPreview) findViewById(R.id.camera_preview); 
    } 
} 

Прежде всего, убедитесь, что setContentView, прежде чем что-либо еще, может вызвать компонент для вашего макета. Возможно, это было проблемой для вас

+1

Кроме того, вам потребуется реализовать двухпараметрический конструктор на вашем «CameraPreview», который принимает «Контекст» и «АтрибутСеть». – CommonsWare

+0

Извините, Лукас, но это делает InflateException. Активность, показанная выше, является просто испытанием. – Ranandar

+0

Вы делали то, что говорили об общем? –

Смежные вопросы