【问题标题】:How to hide action bar before activity is created, and then show it again?如何在创建活动之前隐藏操作栏,然后再次显示?
【发布时间】:2012-01-19 23:30:51
【问题描述】:

我需要在我的蜂窝应用程序中实现启动画面。 我在活动的 onCreate 中使用此代码来显示启动画面:

setContentView(R.layout.splash);
getActionBar().hide();

这段代码会在一段时间后显示主 UI:

setContentView(R.layout.main);
getActionBar().show();

但是 onCreate 被调用并出现splash 之前,有一小段时间显示action bar。

如何使操作栏不可见?

我尝试将主题应用于没有操作栏的活动:

<item name="android:windowActionBar">false</item>

但在这种情况下 getActionBar() 总是返回 null,我找不到再次显示它的方法。

【问题讨论】:

标签: android android-3.0-honeycomb android-actionbar


【解决方案1】:

设置android:windowActionBar="false" 确实会禁用ActionBar,但正如您所说,getActionBar(); 返回 null。 这是通过以下方式解决的:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    getActionBar().hide();

    setContentView(R.layout.splash); // be sure you call this AFTER requestFeature

这会创建 ActionBar 并在它有机会显示之前立即隐藏它。

但是现在还有另一个问题。将windowActionBar="false" 放入主题后,Activity 将绘制其正常的 Window Title 而不是 ActionBar。
如果我们尝试通过使用一些 *.NoTitleBar 股票主题来避免这种情况,或者我们尝试将 &lt;item name="android:windowNoTitle"&gt;true&lt;/item&gt; 放在我们自己的主题中,那么它将不起作用。
原因是 ActionBar 依赖 Window Title 来显示自己 - 也就是说 ActionBar 是一个转换后的 Window Title。
因此,可以帮助我们的诀窍是在我们的 Activity 主题 xml 中再添加一件事:

<item name="android:windowActionBar">false</item>
<item name="android:windowTitleSize">0dp</item>

这将使窗口标题的高度为零,因此实际上是不可见的。

在你的情况下,在你完成显示启动画面后,你可以简单地调用

setContentView(R.layout.main);
getActionBar().show();

你就完成了。 Activity 开始时不会闪烁 ActionBar,也不会显示 Window Title。

插件: 如果您多次显示和隐藏 ActionBar,您可能已经注意到 first 显示是 not 动画的。从那时起,显示和隐藏都是动画的。如果你也想在第一次放映时有动画,你可以使用这个:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_ACTION_BAR);

    // delaying the hiding of the ActionBar
    Handler h = new Handler();
    h.post(new Runnable() {     
        @Override
        public void run() {
            getActionBar().hide();
        }
    });

同样的事情可以通过以下方式实现:

protected void onPostResume() {
    super.onPostResume();
    getActionBar().hide();

但它可能需要一些额外的逻辑来检查这是否是 Activity 的第一次显示。

这个想法是稍微延迟ActionBar的隐藏。在某种程度上,我们让 ActionBar 显示出来,然后立即隐藏它。因此,我们超越了第一次非动画放映,下一次放映将被视为第二次放映,因此它将被动画化。

正如您可能已经猜到的,有可能在 ActionBar 被延迟操作隐藏之前可以看到。实际情况就是这样。大多数情况下什么都看不到,但偶尔,您会看到 ActionBar 闪烁一瞬间。

无论如何,这不是一个很好的解决方案,所以我欢迎任何建议。

添加 v7支持actionbar用户,代码为:

getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();

【讨论】:

  • @newton_guima 是的,它确实有效。只要记住使用 supportRequestWindowFeature(Window.FEATURE_ACTION_BAR)
  • @Cleric - 你如何让这一切与setTheme一起工作?因为如果我从 Manifest 设置主题,您的答案效果很好,但是如果我在 onCreate 中这样做(在我的情况下,主题取决于对深色主题的偏好),默认的全息操作栏会在我设置的之前闪烁无论如何,在我的主题中。但也许这值得另一个完整的 SO 问题。
  • @Cleric 谢谢。我解决了我的问题设置android:theme="@android:style/Theme.NoTitleBar" 进入清单,然后setTheme(R.style.MyTheme) 进入主要活动的onCreate;这确保(在 Android 4+ 中)避免在我在主题中定义的那个之前默认全息 ActionBar 的闪烁(我来到这里寻找一种解决此问题的方法;我实际上不需要任何闪屏)。
  • 我在getWindow().requestFeature(Window.FEATURE_ACTION_BAR); 之后打电话给getSupportActionBar().hide();,一切都被NPE 搞砸了。有任何想法吗? Theme.AppCompat 有问题?
  • @loeschg:我遇到了同样的问题并找到了这个解决方案:stackoverflow.com/a/20315456/3514976
【解决方案2】:

在您的 .class 文件中使用这个简单的代码来隐藏操作栏

getSupportActionBar().hide();

【讨论】:

    【解决方案3】:

    如果您使用的是 ActionBarSherlock,请在您的 Activity 中使用 Theme.Sherlock.NoActionBar 主题

    <activity 
        android:name=".SplashScreenActivity"
        android:theme="@style/Theme.Sherlock.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    

    【讨论】:

    • 这同样适用于标准 Android 3+ ActionBar(无 Sherlock):&lt;activity android:theme="@android:style/Theme.NoActionBar"&gt;
    • 完美解决方案 :) 谢谢。
    • 我不明白这是对 Ilya 问题的回答。将主题设置为Theme.Sherlock.NoActionBar 将意味着调用getActionBar()getSupportActionBar()(随后显示操作栏)返回null...
    • @AlexSemeniuk 当我在清单中使用该行时,我收到此错误:error: Error: No resource found that matches the given name (at 'theme' with value '@android:style/ Theme.NoActionBar').
    • @SiKni8 你确定你的应用程序使用的是 API13+ 库吗?
    【解决方案4】:

    创建两种样式:

    <style name="AppThemeNoBar" parent="Theme.AppCompat.Light">
         <item name="android:windowNoTitle">true</item>
    </style>
    
    <style name="AppThemeBar" parent="Theme.AppCompat.Light">
        <item name="android:windowNoTitle">false</item>
    </style>
    

    将 AppThemeNoBar 设置为应用程序主题,将 AppThemeBar 设置为要显示 ActionBar 的活动。 使用两种样式,在加载视图时您不会看到操作栏。

    查看此链接Android: hide action bar while view load

    【讨论】:

    • 终于!为我工作。谢谢。 :)
    • 这不适用于带有 AppCompat 的 Android 2.3.3。显示操作栏。但是,这适用于即 KitKat。
    【解决方案5】:

    您好,我有一个使用 2 个主题的简单解决方案

    1. 启动画面主题(将其添加到清单中):

      <style name="SplashTheme" parent="@android:style/Theme.Holo.NoActionBar"> <item name="android:windowBackground">@color/red</item> </style>

    2. 普通主题(通过 setTheme(R.style.Theme) 将其添加到您的活动中):

      <style name="Theme" parent="@style/Theme.Holo"> <item name="android:windowBackground">@color/blue</item> </style>

    支持 SDK 10:

    @Override    
    public void onCreate(Bundle savedInstanceState) {
    
        setTheme(R.style.Theme);      
        super.onCreate(savedInstanceState);
    
          ...........
          ...........
    }
    

    【讨论】:

      【解决方案6】:

      我还尝试在 Android 2.2 上隐藏操作栏,但这些解决方案都不起作用。一切都以崩溃告终。我检查了 DDMS 日志,它告诉我使用 'Theme.AppCompat'。最后我通过更改 android:theme="@android:style/Theme.Holo.Light.NoActionBar"Line 解决了这个问题

      进入android:theme="@style/Theme.AppCompat.NoActionBar",它成功了,但是界面很暗。

      然后我尝试了android:theme="@style/Theme.AppCompat.Light.NoActionBar",终于得到了我想要的。

      在那之后,当我在Developer Site I got This. 上搜索“AppCompat”时

      所以我认为 Android 2.2 的解决方案是

      <activity
          android:name=".MainActivity"
          android:theme="@style/Theme.AppCompat.Light.NoActionBar" >
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>
      

      很抱歉我的英语不好,一如既往。

      【讨论】:

        【解决方案7】:

        对我来说最好的结果是使用 ThemeNoTitleBar 创建一个活动,并且没有内容作为启动器。然后这个活动直接调用另一个。

        当然,如果您愿意,您可以向 Splash Activity 添加内容,但在我的情况下,我只想直接显示应用程序。

        清单:

        <activity
                android:name="com.package.SplashActivity"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        

        活动:

        public class SplashActivity extends Activity{
        
        @Override
        protected void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
        
            //start StartActivity
            Intent intent = new Intent(this, StartActivity.class);
            startActivity(intent);
            finish();
        }
        

        }

        【讨论】:

          【解决方案8】:

          如果您使用包含启动画面的Activity,那么如果您使用SherlockActionBar,则可以这样做

          getSupportActionBar().hide();
          

          在启动画面之后,您可以使用 ...再次显示它

          getSupportActionBar().show();
          

          应该和Android原生的ActionBar一样。

          【讨论】:

            【解决方案9】:

            @Clerics 解决方案有效。但这似乎也是一些谷歌原生应用程序的问题:谷歌、游戏商店、谈话。还有其他大型应用程序,例如 Skype。

            编辑:波纹管解决方案在 api

            在您的应用程序或活动标签内的清单中添加以下内容:

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

            然后在你的主要活动中:

                // Set theme
                setTheme(R.style.YOUR_THEME);
                getSupportActionBar().setTitle(R.string.title);
            
                // Start regular onCreate()
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
            

            【讨论】:

              【解决方案10】:

              最好的和简单的

              requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

              【讨论】:

                【解决方案11】:

                2015,使用带有 AppCompat 主题的 support v7 库,为您的 Activity 设置此主题。

                <style name="AppTheme.AppStyled" parent="Theme.AppCompat.Light.DarkActionBar">
                    <item name="colorPrimaryDark">@color/md_indigo_100</item>
                    <item name="colorPrimary">@color/md_indigo_500</item>
                    <item name="colorAccent">@color/md_red_500</item>
                    <item name="android:textColorPrimary">@color/md_white_1000</item>
                    <item name="android:textColor">@color/md_purple_500</item>
                    <item name="android:textStyle">bold</item>
                    <item name="windowNoTitle">true</item>
                    <item name="windowActionBar">false</item>
                </style>
                

                【讨论】:

                  【解决方案12】:

                  对于Splashscreen,您应该在manifest 中使用这一行,不要使用getActionBar()

                  <item name="android:windowActionBar">false</item>
                  

                  当 Splash Activity 在主 Activity 中完成时,使用下面或不使用

                  <item name="android:windowActionBar">true</item>
                  

                  【讨论】:

                  • 如果您为启动页面使用不同的主题而不是应用程序的主页,这实际上是有效的。只需将 android:theme="@style/mytheme" 用于 Main Activity(您的启动屏幕)和您的应用程序的第一个不是启动屏幕交换主题的 Activity。
                  • 这会在当前 API 级别出现错误:“属性缺少 android 命名空间前缀。” &lt;item android:name="android:windowActionBar"&gt;true&lt;/item&gt; 摆脱了这个错误,不知道还能不能用。
                  【解决方案13】:

                  试试这个,它对我有用:

                  下面去掉了activity的标题栏

                   requestWindowFeature(Window.FEATURE_NO_TITLE);
                  

                  下方消除通知栏使活动全屏

                   getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                          WindowManager.LayoutParams.FLAG_FULLSCREEN);
                  

                  (下面的完整示例) 注意:这些方法是在我们设置活动的内容视图之前调用的

                  @Override
                      protected void onCreate(Bundle savedInstanceState) {
                          super.onCreate(savedInstanceState);
                  
                          // Sets Application to full screen by removing action bar
                          requestWindowFeature(Window.FEATURE_NO_TITLE);    
                          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                          WindowManager.LayoutParams.FLAG_FULLSCREEN);
                  
                          setContentView(R.layout.activity_main); 
                  
                          // without this check, we would create a new fragment at each orientation change!
                          if (null == savedInstanceState)
                              createFragment();
                      }
                  

                  【讨论】:

                  • 请说明为什么这样有效,或者为什么您认为这应该有效。仅仅粘贴代码并不能得到完整的答案。
                  • @Kris,哦,我明白你的意思了,谢谢!
                  【解决方案14】:

                  这可能很方便
                  将此添加到您的清单中

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

                  干杯

                  【讨论】:

                  • 为什么要在这么老的问题中发布不如最佳答案的内容?
                  • “最佳答案”对我没有帮助,所以找到了这个答案并将其发布在这里。
                  【解决方案15】:

                  阅读所有可用选项后,我发现最好的方法是在没有 ActionBar 的情况下设置主主题,然后在所有 Activity 的父级代码中设置 MyTheme。

                  清单:

                  <application
                  ...
                          android:theme="@android:style/Theme.Holo.Light.NoActionBar"
                  ...>
                  

                  基础活动:

                  public void onCreate(Bundle savedInstanceState) {
                          super.onCreate(savedInstanceState);
                          setTheme(R.style.GreenHoloTheme);
                  }
                  

                  这种方式可以帮助我在应用程序启动时避免使用 ActionBar!

                  【讨论】:

                    【解决方案16】:

                    已经发布的解决方案带有副作用,即第一个 .show() 调用没有为我设置 ActionBar 的动画。 我得到了另一个不错的解决方案,它解决了这个问题:

                    创建一个透明的可绘制对象 - 类似的东西:

                    <shape xmlns:android="http://schemas.android.com/apk/res/android">
                        <solid
                           android:color="#00000000" />
                    </shape>
                    

                    将实际的操作栏背景设置为您在操作栏上设置的不可见自定义视图:

                    getSupportActionBar().setCustomView(R.layout.actionbar_custom_layout);
                          getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
                                  ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
                    

                    在onCreate中为actionbar设置透明背景:

                    getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.background_transparent));
                    

                    Imortant:不要在 onCreate 中立即隐藏操作栏,但稍后会稍有延迟 - 例如当布局创建完成时:

                    getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                                    @Override
                                    public void onGlobalLayout() {
                                        getSupportActionBar().hide();
                                    }
                                });
                    

                    在您的第一次 .show() 调用之前,将自定义视图设置为可见:

                    _actionbarRoot.setVisibility(View.VISIBLE);
                    getSupportActionBar().show();
                    

                    【讨论】:

                      【解决方案17】:

                      如果您因为使用支持库而有 null,而不是 getActionBar(),您需要调用 getSupportActionBar()

                      【讨论】:

                        【解决方案18】:

                        只需在 onCreate 函数中将其添加到您的 MainActivity。

                        val actionBar = supportActionBar?.apply { hide() }
                        

                        【讨论】:

                        • 它适用于 androidx。只需在 setContentView() 之后添加这一行 supportActionBar?.apply { hide() }
                        【解决方案19】:

                        将您的初始屏幕放在一个单独的活动中,并使用主要活动的onCreate 方法中的startActivityForResult 来显示它。这是有效的,因为根据文档:

                        作为一种特殊情况,如果您在活动的初始 onCreate(Bundle savedInstanceState)/onResume() 期间使用 requestCode >= 0 调用 startActivityForResult(),则在从返回结果之前不会显示您的窗口开始的活动。这是为了避免在重定向到另一个活动时出现明显的闪烁。

                        只有当onCreate 的参数是null(表示您的活动重新启动,而不是由于配置更改而重新启动)时,您才应该这样做。

                        【讨论】:

                        • 这不起作用。当 onCreate() 启动时,操作栏已经可见。这在调试中很明显。
                        【解决方案20】:

                        我仍然有空指针错误,最后当我调用第一个 getWindow().requestFeature() 然后 super.onCreate() 时它有所帮助

                        public void onCreate(Bundle savedInstanceState) {
                        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
                        super.onCreate(savedInstanceState);
                        getActionBar().show();
                        

                        【讨论】:

                          【解决方案21】:

                          只需将其添加到您的 styles.xml 中

                          <item name="android:windowNoTitle">true</item>
                          

                          【讨论】:

                            【解决方案22】:

                            实际上,您可以简单地将 splash Activity 设置为 NoActionBar 并使用操作栏设置您的主要activity

                            【讨论】:

                              【解决方案23】:

                              执行此操作的最佳方法是两个将第一个活动设为空白活动和您要放置的内容,然后在一段时间后触发另一个活动。 通过这种方式,您可以将第一个活动作为启动屏幕,而无需操作栏或任何东西。 这是我的第一个活动

                              package com.superoriginal.rootashadnasim.syllabus;
                              
                              import android.content.Intent;
                              import android.os.Handler;
                              import android.support.v7.app.AppCompatActivity;
                              import android.os.Bundle;
                              
                              public class first_screen extends AppCompatActivity {
                              
                              
                              
                              @Override
                              protected void onCreate(Bundle savedInstanceState) {
                                  super.onCreate(savedInstanceState);
                                  setContentView(R.layout.activity_first_screen);
                              
                              
                                  final Handler h=new Handler();
                                  h.postDelayed(new Runnable() {
                                      @Override
                                      public void run() {
                                          Intent intent=new     Intent(getApplicationContext(),DrawerChooseBranchMainActivity.class);
                                          startActivity(intent);
                                      }
                                  },2000);
                              
                              }
                              }
                              

                              之后,您可以将任何活动作为第一个活动 如果您不想在任何屏幕上都没有操作栏,那么只需将其添加到您的样式中

                                  <item name="windowActionBar">false</item>
                                  <item name="windowNoTitle">true</item>
                              

                              【讨论】:

                                【解决方案24】:

                                Android Studio 提供了全屏的构建模板,如果您使用 Android Studio,您可以按照以下步骤实现全屏活动。

                                完成。 Android Studio 完成了你的工作,现在你可以全屏检查代码了。

                                【讨论】:

                                  【解决方案25】:

                                  这是我用过的最好的方法 转到java文件,在onCreate之后:

                                  @Override
                                      protected void onCreate(Bundle savedInstanceState) 
                                      { 
                                          super.onCreate(savedInstanceState); 
                                          setContentView(R.layout.activity_main); 
                                  
                                          // Take instance of Action Bar 
                                          // using getSupportActionBar and 
                                          // if it is not Null 
                                          // then call hide function 
                                          if (getSupportActionBar() != null) { 
                                              getSupportActionBar().hide(); 
                                          } 
                                      }
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    我知道发布链接并不是最好的方法,但我强烈建议您阅读以下来自 Google 的文档。这是关于如何控制系统 ui(操作栏、导航栏等)的官方 android 文档。不幸的是,信息太多,无法直接发布,但是阅读本文后,您将确切地了解无论您正在开发什么版本,如何显示和隐藏功能,就是这么简单!

                                    如果链接发生变化,可以在 training -> getting started -> 用户界面的最佳实践下的官方 android 文档下找到它strong> -> 管理系统界面

                                    https://developer.android.com/training/system-ui/index.html

                                    【讨论】:

                                      【解决方案27】:

                                      你可以用这个:

                                      getSupportActionBar().hide(); 如果它不起作用,试试这个:

                                      getActionBar().hide();
                                      

                                      如果上述方法不起作用,请尝试这样:

                                      在你的目录= res/values/style.xml ,打开style.xml -> 属性parent 改为parent="Theme.AppCompat.Light.DarkActionBar"

                                      如果所有这些都不起作用。我不知道了。但对我来说它有效。

                                      【讨论】:

                                      • getSupportActionBar().hide();在投票最高的答案 getActionBar().hide() 中被提及;问题中提到了,而 Son Nguyen Thanh 的回答中提到了 DarkActionBar。再加上这个问题已有 4 年历史,并且已经有几个高票的答案。
                                      猜你喜欢
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2017-12-13
                                      • 1970-01-01
                                      • 1970-01-01
                                      相关资源
                                      最近更新 更多