您需要在此活动中使用Theme.AppCompat主题(或后代)


1004

Android Studio 0.4.5

用于创建自定义对话框的Android文档:http : //developer.android.com/guide/topics/ui/dialogs.html

如果需要自定义对话框,则可以将“活动”显示为对话框,而不是使用Dialog API。只需创建一个活动,然后在<activity>清单元素中将其主题设置为Theme.Holo.Dialog即可:

<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; 导入android.support.v7.app.ActionBar; 导入android.support.v4.app.Fragment; 但不确定这一切意味着什么。
ant2009年

10
您正在使用AppCompat支持库的形式来支持api级别11以下的操作栏。仅android:theme="@style/AppTheme" >用于清单中的活动
Raghunandan 2014年

2
@ ant2009,以澄清@Raghunandan所说的内容:在您的中AndroidManifest.xml,您为活动指定的主题将覆盖为应用程序指定的主题。android:theme<activity>标签中删除该行。
cryptochronoconolite

3
这样做将消除错误,但不会使他到达他希望成为对话框主题活动的位置。一般规则是,如果您希望您的活动具有操作栏,则它应具有AppCompat主题,并且Java代码应扩展ActionBarActivity。如果您有不需要动作栏的活动(例如以对话框为主题的活动),则可以对其应用任何主题,但是Java代码必须扩展普通的旧活动。
Bobbake4 2014年

1
我认为在这种情况下,唯一的问题是您为Dialog承包商提供的上下文。看我的答案。stackoverflow.com/a/51574281/232727
Vitaliy A

Answers:


1123

您遇到此问题的原因是,您尝试将对话框主题应用到的活动正在扩展ActionBarActivity,这需要AppCompat应用主题。

更新:扩展 AppCompatActivity也会有此问题

在这种情况下,请将Java继承从更改ActionBarActivityActivity,并将对话框主题原样保留在清单中,这是一个非Theme.AppCompat


一般规则是,如果您希望代码支持较旧的Android版本,则应具有AppCompat主题,并且Java代码应该扩展AppCompatActivity。如果您有不需要此支持的活动,例如您只关心Android的最新版本和功能,则可以对其应用任何主题,但是Java代码必须扩展为old Activity


注意:从AppCompatActivity(或子类ActionBarActivity)更改为时,Activity还必须将带有“支持”的各种调用更改为没有 “支持” 的相应调用。因此getSupportFragmentManager,请致电代替getFragmentManager


6
op正在使用appcompat,在这种情况下,他应该扩展ActionBarActivity该内容,这是从他的import语句(在问题下方的注释中)显示的内容。
Raghunandan 2014年

2
@Bursos如果您在谈论在Android Studio中创建新项目时,我猜这是标准配置中的错误。
Bobbake14年

2
@ Bobbake4,我遇到了同样的问题,这种解决方案对我来说是行不通的。问题是我无法扩展Activity,因为我有一堆基于ActionBarActivity的类(整个项目)。还有其他解决方法吗?Thx
5er 2014年

6
@ 5er如果您的Java使用的是ActionBarActivity,则该主题必须扩展Theme.AppCompat。有一些内置主题可以扩展Theme.AppCompat,或者您可以自己扩展并修改它。如果不删除ActionBarActivity父级,则无法使用Theme.AppCompat。
Bobbake4 2014年

26
在样式<style name =“ AppTheme” parent =“ Theme.AppCompat.Light.DarkActionBar”>中,这解决了我的问题。:)
Harmeet Singh 2014年

545

您需要做的就是将添加android:theme="@style/Theme.AppCompat.Light"AndroidManifest.xml文件中的应用程序标签中。


2
在代码中,ant2009将AppTheme设置为应用程序,它们是从Theme.AppCompat的后代扩展而来的。那应该工作。在设备上升级到5.0后,我遇到了同样的问题,并最终在活动中将@ style / Theme.AppCompat.Light设置为主题。这里
不对劲

36
这不是Android Studio的有效答案,尽管在某些情况下,绕过styles.xml文件时,它可以作为快速解决方案。在Android Studio中,定义主题的正确方法是在styles.xml文件中定义它们,然后Android清单文件仅引用它们,然后根据您设备上运行的Android版本选择它们。通常将其设置为android:theme =“ @ style / AppTheme”,并且此AppTheme引用styles.xml中的<style name =“ Theme.AppTheme” parent =“ Theme.AppCompat.Light”>
zeeshan

5
这对我而言真的不起作用,因为当我使用除holo外的任何内容时,标题栏都消失了
AndyD273

1
也可以使用SnackBar解决此问题。这解决了我的问题。
工作

2
@Martin如果您像我一样,则忘了在通用文件styles.xml中添加与在(V21)styles.xml文件中添加的样式名称相同的名称(没有特定于V21的属性)。如果您在V21文件夹中声明样式,并且您的设备具有以下版本。它找不到它,因此引发了异常。
letroll '16

275

复制@MarkKeen在上面的评论中的答案,因为我有同样的问题。

我在帖子顶部指出了错误,并且在添加警报对话框后发生了该错误。我在清单中有所有相关的样式信息。通过更改警报构建器中的上下文引用,我的问题得以解决-我进行了更改:

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

至:

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

再也没有问题了。


5
我也发生了 我只是在尝试,您的回答确实有效!它起作用的逻辑是什么?我真的不明白
kirtan403

6
或者,如果要在片段中而不是直接在活动中构建AlertDialog,请使用getActivity()而不是this上面建议的方法,这样问题就得到解决。至于为什么,我只能推测旧的AlertDialog.Builder(xxx)代码要么想要传入一个不同的类型,要么对传入的内容不那么挑剔,而当前的Builder()确实确实想要一个Activity。由于Google选择隐藏(删除?)旧代码的文档,大概是为了鼓励使用v7.app版本,因此我无法确定。
安妮·冈恩

是否与建议相反。它的工作:P。谢谢!
Harisewak

1
这为我解决了程序getContext()this如果您在ArrayAdapter或类似的适配器类中,也可以使用它。
Ibrahim.H

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

编辑:

我可能误读了op post。

似乎op想要一个带有活动主题的对话框。因此,如Bobbake4所建议的,extend 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 2014年

@ ant2009您不会。使用支持库AppCompat中的主题进行活动
Raghunandan

我不确定我是否正确添加了这个主题。但是,您的意思是添加以下import语句吗?导入android.support.v7.appcompat。*; 但是,我确实尝试过,也许我错了,因为我仍然遇到同样的异常。
ant2009年

@ ant2009,您可以有一个自定义对话框。但是您要全屏对话吗?
Raghunandan 2014年

我不想全屏显示。只是一个对话框。但是,问题现在已经解决。Bobbake4正确了。无论如何,感谢您的努力,您已提供了有用的建议。但是,我仍然对所有这些支持库和AppCompat感到困惑。
ant2009年

99

如果您使用的是应用程序上下文,则如下所示:

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

将其更改为这样的活动上下文:

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

如果您使用的是LayoutInflater.from(<aplication context>),请确保使用活动上下文或提供的LayoutInflater,以使其继承正确的Theme。
lbarbosa

1
在我的情况下,您的解决方案对我有所帮助。您能解释一下getApplicationContext()和MainActivity.this之间的区别吗?
kostyabakay


9
您需要一个活动而不是上下文来显示对话框
相信

这个解决方案解决了它
Mohamed Amin

45

即使我的主题是AppCompat主题,而我的活动是AppCompatActivity(或Activity其他人的答案所建议的),我也遇到了这个问题。因此,我清理,重建并重新运行了该项目。

构建->清洁项目;构建->重建项目;运行->运行

看起来似乎很蠢,但现在效果很好

希望对您有所帮助!


1
将DialogFragment添加到AppCompat活动后,出现了完全相同的消息。文件,无效缓存/重新启动修复了紧要关头。
halxinate '16

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在setTheme行上抛出NullPointerException。知道为什么吗?
Rhys Davis

@RhysDavis很难说没有堆栈跟踪,但也许它想先使用setContentView?在这种情况下,此修复程序将对您不起作用。
k29

19

去你的风格,把父母

parent="Theme.AppCompat"

代替

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

为什么我们可以通过标准活动来做到这一点。Android是否没有在ICS或Honecomb的“标准活动”上添加动作栏?如果我们将最低目标设置为SDK ICS,是否总是需要使用ActionBarActivity?
安德鲁·S

如何查看我们应该使用哪种主题以及所使用的类型或功能,因为导入时我们拥有所有可用的主题类型
blackHawk

16

就我而言,我的res目录中没有values-v21文件。然后我创建了它,并在其中添加了以下代码:

  <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 +设备上运行我的项目,只有这个对我有用。
Nishant Soni,

16

更改所需活动的主题。这对我有用:

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

14

即使该活动确实使用Theme.AppCompat,我在三星设备上还是发生了此类崩溃。根本原因与三星方面的怪异优化有关:

- 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
只是也遇到了这个问题,我尚未验证此修复程序,无法重现该错误。.但是我仅在三星设备上看到此错误。大多数似乎也是根植,FWIW
danb

我在帖子顶部指出了错误,并且在添加警报对话框后发生了该错误。我在清单中有所有相关的样式信息。通过更改警报构建器中的上下文引用,我的问题得以解决-我将新的android.support.v7.app.AlertDialog.Builder(getApplicationContext())更改为:新的android.support.v7.app.AlertDialog.Builder(this ),没有其他问题了……
马克·基恩

您是否有更多关于此优化的详细信息或与三星的链接?然后所有活动都必须实现Theme.AppCompat还是有没有主题的活动?
AAverin

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. -->

如果将应用程序的主要主题设置为android:Theme.Material.Light而不是AppTheme.Base,则将收到“ IllegalStateException:您需要为此活动使用Theme.AppCompat主题(或后代)”错误。


13

做就是了

new AlertDialog.Builder(this)

代替

new AlertDialog.Builder(getApplicationContext())

工作解决方案!30分钟找出答案。为什么要使用新的AlertDialog.Builder(getApplicationContext())?
ErichGarcía18年

解释this期望的类型将是有帮助的。
Blago

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

以我为例,当我尝试显示Dialog时出现了此类问题。问题是在上下文中,我使用了getBaseContext(),该方法理论上应该返回Activity上下文,但看起来不是,或者在应用任何Theme之前返回上下文。

因此,我只是将getBaseContexts()替换为“ this ”,现在它可以按预期工作。

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

我正在通过getApplicaitonContext(),但是您的方法成功了
Jeeva

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

对我来说是使用ContextThemeWrapper的解决方案:

private FloatingActionButton getFAB() {
Context context = new android.support.v7.view.ContextThemeWrapper(getContext(), R.style.AppTheme);
FloatingActionButton fab = new FloatingActionButton(context);
return fab;}

Android-如何以编程方式创建FAB?



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

之所以来到这里,是因为您想要在sdk以前的版本中将主题设计中的Material Design应用于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. 您应该使用ActivityFragmentActivity而不是ActionbarActivityAppCompatActivity

  2. 如果要使用ActionbarActivityAppCompatActivity,则应将styles.xml Theme.Holo.xxxx更改为Theme.AppCompat.Light(如有必要,请添加到DarkActionbar

如果您不需要有关操作栏或AppCompat的高级属性,则无需使用ActionbarAppCompat


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>
shikha

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

这是我的解决方案。


您是正确的,不应使用原来的方式使用Application上下文。您要做的是改用Activity作为上下文。但是,这不是Application上下文或其子类。因此,以不同的方式使用应用程序上下文是不正确的。
Hod

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更改为ActivityFragmentActivity,它将解决此问题。

如果不使用操作栏,则:

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">

对我没有帮助,例外仍然会触发
Eugene Gr。Philippov

3

这个解决方案对我有用。

设计库取决于Support v4和AppCompat支持库,因此不要在gradle中为appcompat和设计库使用不同的版本。

采用

 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'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.