Galat mengembang saat memperluas kelas

188

Saya mencoba membuat tampilan khusus GhostSurfaceCameraViewyang diperluas SurfaceView. Ini file definisi kelas saya

GhostSurfaceCameraView.java:

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

    GhostSurfaceCameraView(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.release();
        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);
        parameters.set("orientation", "portrait");
        // parameters.setRotation(90); // API 5+
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
}

Dan ini ada di ghostviewscreen.xml saya:

<com.alpenglow.androcap.GhostSurfaceCameraView android:id="@+id/ghostview_cameraview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>

Sekarang dalam aktivitas yang saya buat:

protected void onCreate(Bundle savedInstanceState) {
    try {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ghostviewscreen);
    }
}

Saat setContentView()dipanggil, pengecualian dilemparkan:

Binary XML file 09-17 22:47:01.958: ERROR/ERROR(337):
ERROR IN CODE:
android.view.InflateException: Binary
XML file line #14: Error inflating
class
com.alpenglow.androcap.GhostSurfaceCameraView

Adakah yang bisa memberi tahu saya mengapa saya mendapatkan kesalahan ini? Terima kasih.

eksentrik
sumber

Jawaban:

369

Saya pikir saya tahu mengapa ini tidak berhasil. Saya hanya menyediakan konstruktor untuk kasus satu parameter 'konteks' ketika saya seharusnya menyediakan konstruktor untuk dua parameter 'Konteks, kasus AttributeSet'. Saya juga perlu memberikan konstruktor (s) akses publik. Inilah perbaikan saya:

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

        public GhostSurfaceCameraView(Context context)
        {
            super(context);
            init();
        }
        public GhostSurfaceCameraView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            init();
        }
        public GhostSurfaceCameraView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
eksentrik
sumber
4
Terkadang hal-hal paling sederhana bisa menjadi masalah :) baik untuk mengetahui bahwa kedua parameter digunakan untuk menggembungkan.
Warpzit
5
Terima kasih!! Tidak ada contoh di mana saya bisa menemukan menyebutkan tentang perlunya kelebihan semua konstruktor! Anda menghemat waktu (hari?) Saya.
Scott Biggs
1
Terima kasih banyak! Pesan kesalahannya cukup tidak spesifik, yang membuat saya bingung sejenak, mereka seharusnya memasukkan alasannya (hilang konstruktor yang berlebihan) dalam pesan kesalahan mereka.
AgentKnopf
1
Terima kasih untuk ini. apakah ada yang tahu jika ini berlaku untuk pandangan khusus? Anda perlu menyertakan kedua konstruktor setiap kali Anda membuat tampilan khusus? (konteks, lalu konteks dan atribut)
Tim
2
O, seharusnya sudah melihatnya sebelumnya! Pesannya View is not using the 2- **OR** 3-argument View constructorsagak menyesatkan.
Attacktive
45

@ Tim - Kedua konstruktor tidak diperlukan, hanya ViewClassName(Context context, AttributeSet attrs )konstruktor yang diperlukan. Saya menemukan ini dengan cara yang menyakitkan, setelah berjam-jam menghabiskan waktu.

Saya sangat baru dalam pengembangan Android, tetapi saya membuat tebakan liar di sini, bahwa itu mungkin karena fakta bahwa kita menambahkan Viewkelas khusus dalam file XML, kita menetapkan beberapa atribut padanya dalam XML, yang perlu untuk diproses pada saat Instansiasi. Seseorang yang jauh lebih berpengetahuan dari saya akan dapat menjelaskan lebih jelas tentang masalah ini.

KVNam
sumber
Ini masuk akal, custom TextView saya selalu dibangun dengan ViewClassName (Konteks konteks, attr AttributeSet) ketika saya mendefinisikan atribut untuk itu di xml. Jika saya instantiate tanpa mendefinisikan dalam file xml, konstruktor biasa dipanggil dengan hanya konteks, ViewClassName (Konteks konteks). Saya bertanya-tanya apa yang konstruktor lain lakukan dan menurut ini: stackoverflow.com/a/4022916/1505341 jawaban, itu seharusnya digunakan untuk menetapkan gaya dasar untuk tampilan.
Kerem
19

Penyebab lain yang mungkin dari pesan "Error inflating class" bisa salah mengeja nama paket lengkap yang ditentukan dalam XML:

<com.alpenglow.androcap.GhostSurfaceCameraView android:id="@+id/ghostview_cameraview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>

Membuka file XML layout Anda di editor Eclipse XML akan menyoroti masalah ini.

Ya ampun
sumber
2
Ini memang perbaikan untuk aplikasi saya. com.zerokol.views.joystickview Menjadi com.zerokol.views.JoystickView Dan itu berhasil!
Andy
benar. Lakukan pengecekan ulang ejaan atau coba bekerja menggunakan niat yang disediakan oleh IDE Anda, mulailah dengan mengetikkan nama paket Anda dan semua kelas availbale Anda akan ditampilkan di bawah niat.
Khay
ini adalah kasus saya.
Banee Ishaque K
2

Sangat penting untuk menulis jalur kelas penuh di xml. Saya mendapat 'Kesalahan menggembungkan kelas' saat hanya nama subclass yang ditulis.

Mykola
sumber
Ini sangat mirip dengan apa yang disarankan oleh @rmtheis. Mungkin lebih baik untuk mengomentari jawabannya atau bahkan mengeditnya dengan info tambahan.
Ilia Barahovski
1

Saya memiliki kesalahan ini mengganggu saya selama beberapa jam terakhir. Ternyata, saya telah menambahkan lib tampilan kustom sebagai modul di Android Studio, tetapi saya lalai menambahkannya sebagai ketergantungan pada aplikasi build.gradle.

dependencies {
    ...
    compile project(':gifview')
}
Ionoclast Brigham
sumber
1

fwiw , saya menerima kesalahan ini karena beberapa inisialisasi kustom dalam konstruktor yang mencoba mengakses objek nol.

Tom Howard
sumber
0

Saya memiliki masalah yang sama dalam memperpanjang TextEdit. Bagi saya kesalahannya adalah saya tidak menambahkan "publik" ke konstruktor. Dalam kasus saya ini berfungsi bahkan jika saya mendefinisikan hanya satu konstruktor, satu dengan argumen Contextdan AttributeSet. Masalah kabelnya adalah bahwa bug hanya muncul ketika saya membangun APK (hangus atau tidak) dan saya mentransfernya ke perangkat. Ketika aplikasi dijalankan melalui AndroidStudio -> RunApp pada perangkat yang terhubung USB, aplikasi tersebut berfungsi.

Nicola Mingotti
sumber
0

dalam kasus saya, saya menambahkan sumber daya siklik seperti itu:

<drawable name="above_shadow">@drawable/above_shadow</drawable>

kemudian diubah menjadi

<drawable name="some_name">@drawable/other_name</drawable>

dan itu berhasil

Evgenii Vorobei
sumber
0

Dalam kasus saya, saya menyalin kelas saya dari tempat lain dan tidak segera menyadari bahwa itu adalah abstractkelas. Anda tidak dapat mengembang kelas abstrak.

YesayaJ
sumber
0

Yang perlu dipahami di sini adalah:

Konstruktor ViewClassName(Context context, AttributeSet attrs )dipanggil ketika menggembungkan customView melalui xml. Anda melihat Anda tidak menggunakan kata kunci baru untuk membuat instance objek Anda yaitu Anda tidak melakukannya new GhostSurfaceCameraView(). Melakukan ini, Anda memanggil konstruktor pertama yaitu public View (Context context).

Sedangkan ketika menggembungkan tampilan dari XML, yaitu saat menggunakan setContentView(R.layout.ghostviewscreen);atau menggunakan findViewById, Anda, TIDAK, bukan Anda! , sistem android memanggil ViewClassName(Context context, AttributeSet attrs )konstruktor.

Ini jelas saat membaca dokumentasi: "Konstruktor yang dipanggil ketika menggembungkan tampilan dari XML." Lihat: https://developer.android.com/reference/android/view/View.html#View(android.content.Context,%20android.util.AttributeSet)

Karenanya, jangan pernah lupakan polimorfisme dasar dan jangan pernah lupa membaca dokumentasi. Menghemat banyak sakit kepala.

Kush
sumber