Вам нужно использовать тему Theme.AppCompat (или потомок) с этим действием


1005

Android Studio 0.4.5

Документация Android для создания пользовательских диалоговых окон: http://developer.android.com/guide/topics/ui/dialogs.html

Если вам нужен пользовательский диалог, вы можете вместо этого отображать Activity в качестве диалога вместо использования Dialog API. Просто создайте действие и установите его тему на Theme.Holo.Dialog в <activity>элементе manifest:

<activity android:theme="@android:style/Theme.Holo.Dialog" >

Однако, когда я попробовал это, я получил следующее исключение:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity

Я поддерживаю следующее, и я не могу использовать что-то больше, чем 10 для мин:

minSdkVersion 10
targetSdkVersion 19

В моих стилях у меня есть следующее:

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

И в моем манифесте у меня есть это для деятельности:

 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:theme="@android:style/Theme.Holo.Light.Dialog"
            android:name="com.ssd.register.Dialog_update"
            android:label="@string/title_activity_dialog_update" >
        </activity>

Создание такого диалогового окна было чем-то, что я прыгал, поскольку я уже закончил макет.

Может кто-нибудь сказать мне, как я могу обойти эту проблему?


2
@Raghunandan, я новичок в этом, но, глядя на мои стили, у меня есть следующее: <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> И у меня есть следующий импорт: import android.support.v7 .app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; Но не уверен, что все это значит.
ant2009

10
Вы используете AppCompatформу поддержки библиотеки для поддержки панелей действий ниже уровня API. Просто используйте android:theme="@style/AppTheme" >для действия в манифесте
Raghunandan

2
@ ant2009, чтобы уточнить, что сказал @Raghunandan: у вас AndroidManifest.xmlтема, которую вы указываете для своей деятельности, имеет приоритет над темой, которую вы указываете для своего приложения. Удалить android:themeстроку из <activity>тега.
криптохроноконолит

3
Выполнение этого удалит ошибку, но не приведет его туда, где он хочет быть, что является действием с темой диалога. Общее правило заключается в том, что если вы хотите, чтобы ваша активность имела панель действий, она должна иметь тему AppCompat, а код Java должен расширять ActionBarActivity. Если у вас есть действие, которому не нужна панель действий (например, диалоговое задание), вы можете применить к ней любую тему, но код java должен расширять простую старую активность.
Bobbake4

1
Я думаю, что единственной проблемой в этом случае является контекст, который вы предоставляете для конструктора диалога. Смотри мой ответ. stackoverflow.com/a/51574281/232727
Виталий А

Ответы:


1125

Причина, по которой у вас возникла эта проблема, заключается в том, что действие, к ActionBarActivityкоторому вы пытаетесь применить тему диалога, расширяется, что требует применения AppCompatтемы.

Обновление : расширение AppCompatActivityтакже будет иметь эту проблему

В этом случае измените наследование Java от ActionBarActivityдо Activityи оставить диалог тему в манифесте , как это, неофициальное Theme.AppCompatзначение


Общее правило заключается в том, что если вы хотите, чтобы ваш код поддерживал более старые версии Android, он должен иметь AppCompatтему, а код Java должен расширяться AppCompatActivity. Если у вас есть * действие, которое не нуждается в этой поддержке, например, если вы заботитесь только о последних версиях и функциях Android, вы можете применить к нему любую тему, но код java должен расширять старый Activity.


ПРИМЕЧАНИЕ. При переходе с AppCompatActivity(или подкласса ActionBarActivity) на Activity, также необходимо изменить различные вызовы с «поддержкой» на соответствующий вызов без «поддержки». Так что вместо getSupportFragmentManagerзвоните getFragmentManager.


6
op использует appcompat, в этом случае он должен расширяться, ActionBarActivityчто показано в его утверждениях import из комментария под вопросом.
Рагхунандан

2
@Bursos Если вы говорите, когда создаете новый проект в Android Studio, я думаю, это ошибка в стандартной конфигурации.
Bobbake4

2
@ Bobbake4, у меня та же проблема, и это решение невозможно для меня. Дело в том, что я не могу расширить Activity, потому что у меня есть куча классов (весь проект), которые передают ActionBarActivity. Есть ли другое решение проблемы? Thx
5

6
@ 5er Если ваша Java использует ActionBarActivity, тема должна расширять Theme.AppCompat. Есть несколько встроенных тем, которые расширяют Theme.AppCompat, или вы можете расширить его и изменить. Без удаления родителя ActionBarActivity вы не сможете обойтись с помощью Theme.AppCompat.
Bobbake4

26
В стиле <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> это решило мою проблему. :)
Хармит Сингх

546

Все, что вам нужно сделать, это добавить android:theme="@style/Theme.AppCompat.Light"тег вашего приложения в AndroidManifest.xmlфайл.


2
В коде ant2009 в качестве приложения их установлено приложение AppTheme, которое происходит от потомка Theme.AppCompat. Это должно работать. У меня возникла та же проблема после обновления до 5.0 на моем устройстве, и я настроил @ style / Theme.AppCompat.Light в качестве темы моей деятельности. Что-то здесь не так ...
speedynomads

36
Это неверный ответ для Android Studio, хотя в некоторых случаях он будет работать как быстрое исправление, если обходить файлы styles.xml. В Android Studio правильным способом определения темы является определение их в файлах styles.xml, а затем файл описания Android будет просто ссылаться на них и выбирать их в зависимости от версии Android, которую вы используете на своем устройстве. Обычно для него установлено значение android: theme = "@ style / AppTheme", и этот AppTheme ссылается на <style name = "Theme.AppTheme" parent = "Theme.AppCompat.Light"> в styles.xml
zeeshan

5
Это действительно не работает для меня, потому что мои заголовки исчезли, когда я использовал что-нибудь, кроме голо ...
AndyD273

1
Столкнулся с этой проблемой также с помощью SnackBar. Это решило мою проблему.
работал

2
@Martin, если вы похожи на меня, вы забыли добавить то же имя стиля в общий файл styles.xml, что и в файл (V21) styles.xml (без свойств, специфичных для V21). Если вы объявите стиль в папке V21, и ваше устройство имеет версию ниже. Это не может найти это, таким образом, исключение уволено.
letroll

275

Копирование ответа от @MarkKeen в комментариях выше, так как у меня была та же проблема.

У меня была ошибка, указанная в верхней части сообщения, и произошла после того, как я добавил диалоговое окно с предупреждением. У меня есть вся соответствующая информация о стиле в манифесте. Моя проблема была исправлена ​​путем изменения ссылки на контекст в конструкторе оповещений - я изменил:

new android.support.v7.app.AlertDialog.Builder(getApplicationContext())

чтобы:

new android.support.v7.app.AlertDialog.Builder(this)

И проблем больше нет.


5
Это случилось со мной тоже. Я просто пытался, и ваш ответ действительно работал! Какова логика для этого, чтобы работать? Я действительно не понял.
kirtan403

6
Или, если вы строите свой AlertDialog во фрагменте, а не непосредственно в Activity, используйте, getActivity()а не thisкак предложено выше, и проблема устранена. Что касается того, почему, я могу только предположить, что более старый код AlertDialog.Builder (xxx) либо хотел передать другой тип, либо просто менее требователен к тому, что было передано, в то время как текущий Builder () действительно действительно хочет Activity. Так как Google решил скрыть (удалить?) Документацию для старого кода, предположительно, в попытке поощрить использование версии v7.app, я не знаю, как точно сказать.
Энн Ганн

Сделал противоположность того, что предлагается. И это сработало: P. Спасибо!
Harisewak

1
Это решит программу для меня, также вы бы использовали getContext()вместо, thisесли вы находитесь внутри ArrayAdapter или аналогичного класса адаптера.
Ибрагим.Н

1
Это подлинное решение, которое я когда-либо встречал. СОВЕТ: Пожалуйста, укажите разницу в getApplicationContext () и это для этой цели.
Празеев

109

min sdk равно 10. ActionBarдоступно на уровне API 11. Таким образом, для 10 вы будете использовать AppCompatиз библиотеки поддержки, для которой вы должны использовать Theme.AppCompatили потомок того же.

использование

android:theme="@style/Theme.AppCompat" >

Или, если вы не хотите панель действий наверху

android:theme="@style/Theme.AppCompat.NoActionBar">

Больше информации @

http://developer.android.com/guide/topics/ui/actionbar.html

Редактировать:

Я мог неправильно прочитать сообщение.

Кажется, что ОП хочет диалог с темой деятельности. Таким образом, как уже предложено Bobbake4, Activityвместо расширения ActionBarActivity.

Также посмотрите @ Атрибуты диалога в ссылке ниже

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/res/res/values/themes.xml/


Спасибо за предложение. Я попробовал это уже на самом деле. И у меня такая же проблема. Мой файл стилей выглядит следующим образом: <style name = "AppTheme" parent = "Theme.AppCompat">
ant2009

@ ant2009 ты не будешь. Используйте тему из библиотеки поддержки AppCompat для своей деятельности
Raghunandan

Я не уверен, правильно ли я добавляю эту тему. Но вы имеете в виду добавление следующего оператора импорта? import android.support.v7.appcompat. *; Тем не менее, я попробовал это, и, возможно, я ошибаюсь, так как все равно оказался с тем же исключением.
ant2009

@ ant2009 вы можете иметь собственный диалог. Но вы хотите полноэкранный диалог?
Рагхунандан

Я не хотел, чтобы это было на весь экран. Просто диалоговое окно. Однако проблема решена уже сейчас. Bobbake4 понял это правильно. В любом случае, спасибо за ваши усилия, вы дали полезный совет. Тем не менее, я все еще запутался со всей этой библиотекой поддержки и AppCompat.
ant2009

99

Если вы используете контекст приложения, вот так:

final AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());

измените его на контекст деятельности, как это:

final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

То же самое, если вы используете LayoutInflater.from (<контекст приложения>), убедитесь, что вы используете контекст действия или предоставленный LayoutInflater, чтобы он наследовал нужную тему.
Ибарбоса

1
Ваше решение помогло мне в моем случае. Можете ли вы объяснить, в чем разница между getApplicationContext () и MainActivity.this?
Костябакай

обратитесь по этой ссылке: stackoverflow.com/questions/22966601/…
Даруш

9
для отображения диалогов необходима активность, а не контекст
behelit

это решение решает его
Мохамед Амин

45

Я столкнулся с этой проблемой, хотя моя Тема была AppCompatТемой, а моя Активность - AppCompatActivity(или Activity, как подсказывалось в ответах других). Поэтому я почистил, перестроил и снова запустил проект.

( Построить -> Очистить проект; Построить -> Перестроить проект; Выполнить -> Выполнить )

Это может показаться глупым, но теперь это прекрасно работает !

Надеюсь, это поможет!


1
После добавления DialogFragment в действие AppCompat было точно такое же сообщение. File, Invalidate Caches / Restart исправили это в крайнем случае.
Halxinate

2
Я перепробовал почти все ответы в этой теме. но только этот, казалось бы, «тупой» ответ работает. благодарю вас!
Дика

27

Это то, что исправило это для меня: вместо того, чтобы указывать тему в манифесте, я определил ее onCreateдля каждого расширяемого действия ActionBarActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.MyAppTheme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity_layout);
...
}

Вот MyAppThemeпотомок Theme.AppCompat, и определяется в XML. Обратите внимание, что тема должна быть установлена ​​до super.onCreateи setContentView.


1
Robolectric генерирует исключение NullPointerException в строке setTheme при попытке загрузить ресурс. Есть идеи почему?
Рис Дэвис

@RhysDavis Сложно сказать без трассировки стека, но, возможно, сначала нужно установить setContentView? В этом случае это исправление не будет работать для вас.
k29

19

перейти к своим стилям и поставить родителя

parent="Theme.AppCompat"

вместо

parent="@android:style/Theme.Holo.Light"

Почему мы можем сделать это со стандартной деятельностью? Разве Android не устанавливал панели действий на Стандартные действия с ICS или Honecomb? Всегда ли нам нужно использовать ActionBarActivity, если мы устанавливаем минимальную цель для SDK ICS?
Андрей С

как узнать, какую тему мы должны использовать с типом или функцией, которую мы используем, потому что когда мы импортируем, у нас есть все типы доступных тем
blackHawk

17

Измените тему желаемого занятия. Это работает для меня:

<activity
            android:name="HomeActivity"
            android:screenOrientation="landscape"
            android:theme="@style/Theme.AppCompat.Light"
            android:windowSoftInputMode="stateHidden" />

16

В моем случае у меня нет файла values-v21 в моей директории res. Затем я создал его и добавил следующие коды:

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Я запускал свой проект на устройствах Oreo +, и только это сработало для меня.
Нишант Сони

14

У меня был такой сбой на устройствах Samsung, хотя активность использовала Theme.AppCompat . Основная причина была связана со странными оптимизациями на стороне Samsung:

- if one activity of your app has theme not inherited from Theme.AppCompat
- and it has also `android:launchMode="singleTask"`
- then all the activities that are launched from it will share the same Theme

Мое решение просто удаляло android:launchMode="singleTask"


2
Просто столкнулся с этим, я не проверил исправление и не могу воспроизвести ошибку ... но я вижу эту ошибку в дикой природе только на устройствах Samsung. большинство, кажется, также укоренились, fwiw
danb

У меня была ошибка, указанная в начале сообщения, и произошла после того, как я добавил диалоговое окно с предупреждением. У меня есть вся соответствующая информация о стиле в манифесте. Моя проблема была устранена путем изменения ссылки на контекст в построителе предупреждений - я изменил: новый android.support.v7.app.AlertDialog.Builder (getApplicationContext ()) на: новый android.support.v7.app.AlertDialog.Builder (это ) и больше никаких проблем ...
Марк Кин

У вас есть какие-либо подробности или ссылки на Samsung об этой оптимизации? Затем все действия должны реализовывать Theme.AppCompat или могут быть действия без темы?
Аверин

13

Если вам нужно расширить ActionBarActivity, вам нужно в вашем style.xml:

<!-- Base application theme. -->
<style name="AppTheme" parent="AppTheme.Base"/>

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->

Если вы установите в качестве основной темы вашего приложения андроид: Theme.Material.Light вместо AppTheme.Base, вы получите сообщение об ошибке «IllegalStateException: вам нужно использовать тему Theme.AppCompat (или потомок) с этим действием».


13

Просто делать

new AlertDialog.Builder(this)

Вместо

new AlertDialog.Builder(getApplicationContext())

Рабочий раствор! 30 минут, чтобы узнать с этим ответом. Почему я использую новый AlertDialog.Builder (getApplicationContext ())?
Эрих Гарсия

Будет полезно объяснить, какой тип thisдолжен быть.
Благо

12

У меня была та же проблема, но она была решена, когда я поместил это в манифест: android: theme = "@ style / Theme.AppCompat.

    <application
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name_test"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat">

        ...    

    </application>

10

В моем случае такая проблема возникла, когда я пытался показать диалог. Проблема была в контексте, я использую getBaseContext (), который теоретически должен возвращать контекст Activity, но, по-видимому, его нет, или он возвращает контекст до применения любой темы.

Поэтому я просто заменил getBaseContexts () на « this », и теперь он работает как положено.

        Dialog.showAlert(this, title, message,....);

я передавал getApplicaitonContext (), но ваш сделал свое дело
Джива

9

У меня была активность с темой, <android:theme="@android:style/Theme.Dialog">используемой для отображения диалога в моем appWidget и у меня была та же проблема

Я решил эту ошибку, изменив код активности, как показано ниже:

@Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.Theme_AppCompat_Dialog); //this line i added
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dialog);
}

2
Это был простой ответ, который работал для меня без всей сложности и отсутствия ответа принятого.
Кори Трез


8

Убедитесь, что вы используете контекст активности при создании нового диалогового окна оповещения, а не приложение или базовый контекст.


7

У меня была и эта проблема, и что я сделал, чтобы ее исправить, И все еще использовал тему Holo, чтобы предпринять следующие шаги:

Сначала я заменил этот импорт:

import android.support.v7.app.AppCompatActivity;

с этим:

import android.app.Activity;

затем изменил мое расширение с:

public class MyClass extends AppCompatActivity {//...

к этому:

public class MyClass extends Activity {//...

А также пришлось изменить этот импорт:

import android.support.v7.app.AlertDialog;

к этому импорту:

import android.app.AlertDialog;

и затем вы можете использовать свой тег темы в манифесте на уровне активности:

android:theme="@android:style/Theme.Holo.Dialog" />

и, наконец, (если в вашем проекте нет других классов, которые должны использовать v7 appCompat), вы можете либо очистить и перестроить свой проект, либо удалить эту запись в файле сборки gradle на уровне приложения:

compile 'com.android.support:appcompat-v7:23.2.1'

если у вас есть другие классы в вашем проекте, которые должны использовать v7 appCompat, просто очистите и пересоберите проект.


6

Вы пришли к этому, потому что хотите применить Material Design в своем стиле темы в предыдущих версиях SDK до 21. ActionBarActivityТребуется, AppThemeпоэтому, если вы также хотите запретить собственную настройку для вашей AppTheme, вам нужно только изменить в вашем styles.xml (предыдущий в SDK 21), таким образом, можно наследовать для темы App Compat.

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">

за это:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

6
Сделал это. Все еще есть проблема. Так что это еще не все.
Мартин,

6

Измените свой родительский стиль темы на

 parent="Theme.AppCompat"

Это сработало для меня ...


6

У вас есть много решений этой ошибки.

  1. Вы должны использовать Activity или FragmentActivity вместо ActionbarActivity или AppCompatActivity

  2. Если вы хотите использовать ActionbarActivity или AppCompatActivity , вам нужно изменить в styles.xml Theme.Holo.xxxx на Theme.AppCompat.Light (при необходимости добавить в DarkActionbar )

Если вам не нужны расширенные атрибуты о панели действий или AppCompat, вам не нужно использовать Actionbar или AppCompat .


6

В манифесте Android просто измените тему действия на AppTheme, как показано ниже.

<activity
  android:name=".MainActivity"
  android:label="@string/app_name"
  android:theme="@style/AppTheme">
</activity>

<activity android: name = ". MainActivity" android: label = "@ string / app_name" android: theme = "@ style / AppTheme"> </ activity>
Шиха,

6

Это когда вы хотите AlertDialog во фрагменте

            AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
            adb.setTitle("My alert Dialogue \n");
            adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {

                  //some code

            } });
            adb.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {

                 dialog.dismiss();

                } });
            adb.show();

6

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

builder = new AlertDialog.Builder(getApplicationContext());

Но контекст был неверным и вызвал ошибку. Я изменил его, используя контекст приложения следующим образом:

В разделе объявления:

Context mContext;

в методе onCreate

mContext = this;

И, наконец, в коде, где мне нужен AlertDialog:

start_stop = (Button) findViewById(R.id.start_stop);
start_stop.setOnClickListener( new View.OnClickListener()
     {
                @Override
                public void onClick(View v)
                {
                    if (!is_running)
                    {
                        builder = new AlertDialog.Builder(mContext);
                        builder.setMessage("MYTEXT")
                                .setCancelable(false)
                                .setPositiveButton("SI", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                    Task_Started = false;
                                    startTask();
                                    }
                                })
                                .setNegativeButton("NO",
                                        new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        dialog.cancel();
                                    }
                                });
                        AlertDialog alert = builder.create();
                        alert.show();
                    }
            }
        }

Это решение для меня.


Вы правы в том, что вам не следует использовать контекст приложения так, как он был у вас изначально. То, что вы сделали, это вместо этого использовали Activity в качестве контекста. Однако это не контекст приложения или его подкласс. Поэтому неправильно говорить, что вы используете контекст приложения по-другому.
Ход

5

Этот работал для меня:

<application
           android:allowBackup="true"
           android:icon="@mipmap/ic_launcher"
           android:label="@string/app_name"
           android:theme="@style/AppTheme" >
           <activity
               android:name=".MainActivity"
               android:label="@string/app_name"
               android:theme="@style/Theme.AppCompat.NoActionBar">

               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />

                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
           </activity>
</application>

5

Ваша активность расширяет ActionBarActivity, которая требует применения AppCompat.theme . Меняться от ActionBarActivity на Activity или FragmentActivity , это решит проблему.

Если вы не используете панель действий, тогда:

android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" 

5

У меня была такая же проблема. Потому что я создавал пользовательский навигационный ящик. Но я забыл упомянуть тему в моем манифесте, как это

android:theme="@style/Theme.AppCompat.NoActionBar"

Как только я добавил вышеупомянутую тему в мой манифест, это решило проблему.


4

Быстрое решение.

Измените родительский элемент вашей базовой темы в styles.xml

Заменить от

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

в

<style name="AppTheme" parent="Theme.AppCompat">

мне не помогает, исключение еще срабатывает
Евгений Гр. Филиппов

3

Это решение сработало для меня.

Библиотека дизайна зависит от Support v4 и библиотек поддержки AppCompat, поэтому не используйте другую версию для appcompat и библиотеки дизайна в gradle.

использование

 compile 'com.android.support:appcompat-v7:23.0.0'
 compile 'com.android.support:design:23.0.0'

вместо

 compile 'com.android.support:appcompat-v7:23.0.0'
 compile 'com.android.support:design:23.1.0'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.