Помилка надуття під час розширення класу


188

Я намагаюся створити спеціальний вид, GhostSurfaceCameraViewякий розширюється SurfaceView. Ось мій файл визначення класу

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();
    }
}

І це в моєму ghostviewscreen.xml:

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

Зараз у діяльності я зробив:

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

Коли setContentView()телефонує, викид викидається:

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

Хтось може мені сказати, чому я отримую цю помилку? Дякую.

Відповіді:


369

Я думаю, я зрозумів, чому це не працює. Я надав конструктор лише для випадку одного параметра "контекст", коли я повинен був надати конструктор для двох параметрів "Контекст, AttributeSet". Мені також потрібно було надати доступ громадськості до конструктора. Ось моє виправлення:

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();
        }

4
Іноді найпростіші речі можуть бути проблемою :) добре знати, що обидва параметри використовуються для роздування.
Warpzit

5
Дякую!! Ніде в прикладах я не можу знайти жодної згадки про необхідність перевантаження всіх конструкторів! Ви заощадили мені години (дні?) Часу.
Скотт Біггс

1
Дуже дякую! Повідомлення про помилку є досить непевним, і мене на мить затуманило, вони повинні були включити причину (відсутність перевантаження конструктора) у своєму повідомленні про помилку.
AgentKnopf

1
спасибі за це. Хто-небудь знає, чи все це відповідає платі за користувацькі перегляди? вам потрібно включати обидва конструктори щоразу, коли ви робите спеціальний перегляд? (контекст, а потім контекст і атрибути)
Тім

2
О, варто було бачити це раніше! Повідомлення View is not using the 2- **OR** 3-argument View constructorsначебто вводить в оману.
Атакуючий

45

@Tim - Обидва конструктори не потрібні, потрібен лише ViewClassName(Context context, AttributeSet attrs )конструктор. Я виявив це болючим шляхом, через години та години витраченого часу.

Я дуже новачок в розробці Android, але тут я гадаю, що це, можливо, пов'язано з тим, що, оскільки ми додаємо нестандартний Viewклас у XML-файл, ми встановлюємо йому кілька атрибутів у XML, що потребує підлягає обробці в момент інстанції. Хтось набагато більш обізнаний, ніж я, зможе прояснити це питання ясніше.


Це має сенс, мій користувальницький TextView завжди будується з ViewClassName (контекст контексту, AttributeSet attrs), коли я визначаю атрибути для нього в xml. Якщо я ініціюю його без визначення у файлі xml, звичайний конструктор викликається лише контекстом, ViewClassName (контекст контексту). Мені було цікаво, що робить інший конструктор, і відповідно до цього: stackoverflow.com/a/4022916/1505341 відповідь, він повинен використовуватися для встановлення базового стилю для подання.
Керем

19

Ще однією можливою причиною повідомлення "Помилка надуття класу" може бути неправильне написання повного імені пакета, де він вказаний у XML:

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

Відкриття вашого файлу XML-макета у редакторі Eclipse XML повинно висвітлити цю проблему.


2
Це справді було виправленням моєї заяви. com.zerokol.views.joystickview Став com.zerokol.views.JoystickView І це спрацювало!
Енді

правда. Зробіть подвійну перевірку орфографії або спробуйте працювати, використовуючи наміри, надані вашим IDE, просто почніть, ввівши назву вашого пакета, і всі ваші класи доступності будуть показані під намірами.
Хай

це був мій випадок.
Banee Ishaque K

2

Важливо написати повний шлях до класу в xml. Я отримав "Помилка надуття класу", коли було написано лише ім'я підкласу.


Це дуже схоже на те, що пропонує @rmtheis. Можливо, краще прокоментувати його відповідь або навіть відредагувати її з додатковою інформацією.
Ілля Бараховський

1

У мене ця помилка мучила останні кілька годин. Виявляється, я додав власну панель перегляду як модуль в Android Studio, але я нехтував її додаванням як залежність у додатку build.gradle.

dependencies {
    ...
    compile project(':gifview')
}

1

fwiw , я отримав цю помилку через деяку власну ініціалізацію всередині конструктора, який намагався отримати доступ до нульового об’єкта.


0

У мене була така ж проблема із розширенням TextEdit. Для мене помилкою було те, що я не додав "public" до конструктора. У моєму випадку це працює, навіть якщо я визначаю лише один конструктор, той, який має аргументи Contextта AttributeSet. Справа в тому, що помилка виявляється лише тоді, коли я створюю APK (співаю чи ні) і передаю його на пристрої. Коли програма запускається через AndroidStudio -> RunApp на пристрої, підключеному USB, програма працює.


0

у моєму випадку я додав такий циклічний ресурс:

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

потім змінено на

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

і це спрацювало


0

У моєму випадку я скопіював свій клас з іншого місця і не помітив відразу, що це abstractклас. Ви не можете надувати абстрактні класи.


0

Тут потрібно розуміти:

Конструктор ViewClassName(Context context, AttributeSet attrs )викликається при надуванні customView через xml. Ви бачите, що не використовуєте нове ключове слово для створення об'єкта, тобто ви цього не робите new GhostSurfaceCameraView(). Роблячи це, ви викликаєте перший конструктор, тобто public View (Context context).

В той час, коли при надуванні подання від XML, тобто при використанні setContentView(R.layout.ghostviewscreen);чи використанні findViewById, ви, НЕ, не ви! , система Android викликає ViewClassName(Context context, AttributeSet attrs )конструктор.

Це зрозуміло, читаючи документацію: "Конструктор, який викликається при надуванні подання від XML." Дивіться: https://developer.android.com/reference/android/view/View.html#View(android.content.Context,%20android.util.AttributeSet)

Отже, ніколи не забувайте про базовий поліморфізм і ніколи не забувайте читати документацію. Це економить тонну головного болю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.