android - 使用 ActionMode 时,Lollipop 状态栏变黑

标签 android statusbar android-actionmode

我有一个状态栏,上面设置了以下主题:

<!-- Base Theme for all "Material"-esque styles. We use NoActionBar
     so we can use the Toolbar at runtime.
-->
<style name="Material" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:windowTranslucentStatus">true</item>
    ...
</style>

我还有一个 DrawerLayout对于我的大多数 Activity ,它会根据我的喜好设置状态栏的颜色:

    mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myapp_green));

我正在使用 Toolbar ,而不是默认的 ActionBar , 所以它存在于我的布局中(即抽屉导航在它上面绘制)。

一切正常,除了在我的一项 Activity 中,我有一个多选模式,ActionMode .当这个 ActionMode被激活(使用长按),它会覆盖 Toolbar使用:

<item name="android:windowActionModeOverlay">true</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeStyle">@style/Material.Widget.ActionMode</item>

Material.Widget.ActionMode风格是:

<style name="Material.Widget.ActionMode" parent="@style/Widget.AppCompat.ActionMode">
    <item name="android:background">@color/myapp_green</item>
    <item name="background">@color/myapp_green</item>
</style>

现在的问题是,每当发生这种情况时,状态栏就会从 myapp_green颜色为黑色。这几乎就像状态栏半透明被关闭(我使用的是 Android 5.0)。我想知道如何才能让这种行为不发生,并保持状态栏颜色/半透明原样。

我尝试添加 <item name="android:windowTranslucentStatus">true</item>到 Action 模式的样式,以及添加<item name="android:statusBarColor">@color/myapp_green</item> ActionMode 的风格,都没有成功。

更新:

我想知道这是否与我设置状态栏背景的古怪方式有关。我所有的 Activity 类都派生自 NavigationDrawerActivity.java:

/**
 * An {@link Activity} that supports a Navigation Drawer, which is a pull-out panel for navigation
 * menus. This drawer is pulled out from the left side of the screen (right side on RTL devices).
 */
public class NavigationDrawerActivity extends ActionBarActivity
  implements AdapterView.OnItemClickListener {

  private static final String LOGTAG = NavigationDrawerActivity.class.getSimpleName();

  private DrawerLayout mDrawerLayout;
  private ListView mDrawerList;
  private LayoutInflater mInflater;
  private NavigationDrawerItemAdapter mAdapter;
  private ActionBarDrawerToggle mDrawerToggle;

  private NavigationDrawerItem[] mNavigationDrawerItems;

  private Toolbar mAppBar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// We have to call super.setContentView() here because BaseActivity redefines setContentView(),
// and we don't want to use that.
super.setContentView(R.layout.navigation_drawer);

mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    setupNavigationDrawer();
  }

  @Override
  protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);

    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
  }

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    switch(id) {
      case android.R.id.home:
        return mDrawerToggle.onOptionsItemSelected(item);
    }

    return super.onOptionsItemSelected(item);
  }

  /**
   * Toggles the state of the navigation drawer (i.e. closes it if it's open, and opens it if
   * it's closed).
   */
  public void toggleNavigationDrawer() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
      closeNavigationDrawer();
    } else {
      openNavigationDrawer();
    }
  }

  /**
   * Opens the navigation drawer.
   */
  public void openNavigationDrawer() {
    mDrawerLayout.openDrawer(GravityCompat.START);
  }

  /**
   * Closes the navigation drawer.
   */
  public void closeNavigationDrawer() {
    mDrawerLayout.closeDrawer(GravityCompat.START);
  }

  /**
   * Initializes items specific to the navigation drawer.
   */
  private void setupNavigationDrawer() {
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.wiw_green));

        mAppBar = (Toolbar) findViewById(R.id.app_bar);
        setSupportActionBar(mAppBar);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
        actionBar.setDisplayShowHomeEnabled(false);

        mDrawerToggle = new ActionBarDrawerToggle(
          this,                  /* Our context (Activity that hosts this drawer) */
          mDrawerLayout,         /* The DrawerLayout where the nav drawer will be drawn */
          R.string.drawer_open,  /* Description of "open drawer", for accessibility */
          R.string.drawer_close  /* Description of "close drawer", for accessibility */
        ) {

          /**
           * Called when a drawer has settled in a completely closed state.
           */
          public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            supportInvalidateOptionsMenu();
          }

          /**
           * Called when a drawer has settled in a completely open state.
           */
          public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            supportInvalidateOptionsMenu();
          }
        };

        mDrawerList = (ListView) mDrawerLayout.findViewById(R.id.drawer_list);

        mNavigationDrawerItems = buildNavDrawerItemsList();

        setupAdapter(mNavigationDrawerItems);

        setupNavigationDrawerHeader();

        mDrawerLayout.setDrawerListener(mDrawerToggle);
        mDrawerList.setOnItemClickListener(this);
      }

      @Override
      public void onItemClick(AdapterView<?> parent, View aView, int aPosition, long aId) {
        // Code not relevant
      }

      /**
       * Set the inner content view of this {@link NavigationDrawerActivity} to have a given layout.
       *
       * @param aLayoutId The id of the layout to load into the inner content view of this activity.
       */
      public void setDrawerContent(int aLayoutId) {
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ViewGroup root = (ViewGroup)findViewById(R.id.drawer_content);
        inflater.inflate(aLayoutId, root);
      }  
    }

我实际上必须运行 DrawerLayout.setStatusBarBackgroundColor()让它发挥作用。刚换colorPrimaryDarkvalues-v21/styles.xml对状态栏没有影响。我觉得这可能是问题的根源......这些类正在从非 Material 主题转换为新的、类似 Material 的主题,所以我想知道在转换到colorPrimaryDark被正确识别。

最佳答案

我在这里发布答案是因为,虽然其他解决方案很有帮助,但没有一个能准确回答这个问题。我能够发现对 DrawerLayout.setStatusBarBackgroundColor() 的调用造成了麻烦。我的解决方案如下:

  1. 启用 windowTranslucentStatuswindowDrawsSystemBarBackgrounds在主题中。

  2. 移除对 DrawerLayout.setStatusBarBackgroundColor() 的调用在我的NavigationDrawerActivity ,其中所有 Activity类派生。

  3. 在我的 values-v21/styles.xml 中设置以下样式基本主题:

    <item name="android:colorPrimary">@color/app_green</item>
    <item name="colorPrimary">@color/app_green</item>
    <item name="android:colorPrimaryDark">@color/app_green_dark</item>
    <item name="colorPrimaryDark">@color/app_green_dark</item>
    <item name="android:colorPrimaryDark">?attr/colorPrimaryDark</item>
    <item name="android:statusBarColor">?attr/colorPrimaryDark</item>
    
  4. NavigationDrawerActivity 内部类,在其onCreate()方法,我执行以下操作(感谢@Tinadm的这部分答案): getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

  5. 在我的类里面展示 ActionMode ,我添加了以下方法:

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        // This is to highlight the status bar and distinguish it from the action bar,
        // as the action bar while in the action mode is colored app_green_dark
        getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.app_green_darker));
      }
    
      // Other stuff...
      return true;
    }
    
    @Override
    public void onDestroyActionMode(ActionMode mode) {
      mActionMode = null;
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.app_green_dark));
      }
    }
    

ActionMode 时重新启用半透明状态栏被破坏使我的抽屉导航能够在状态栏下方绘制。还值得注意的是 ActionMode覆盖操作栏,因此如果在 ActionMode 时将其拉出,它将覆盖抽屉导航已启用(通过从左到右滑动)。我将在 ActionMode 时禁用此功能。已启用,因此不会混淆用户。

关于android - 使用 ActionMode 时,Lollipop 状态栏变黑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30180091/

相关文章:

android - 如何在 Android 工具栏中的 WhatsApp 等操作模式菜单中始终显示 5 个项目

android - Action 模式在 Android 的 ExpandableListView 中不起作用

java - 如何检查从 Android 应用程序发送的电子邮件?或者打算完成(无论发送的电子邮件如何)?

javascript - 当加载网页调整为在加载时将 url 框隐藏在 androids 上时,它叫什么

android - appcompat-v7 :27. 0.1 播放服务 map 问题

iphone - 在 iOS 7 中移动状态栏

wpf - 获取 ProgressBar 来填充 StatusBarItem

android - AlertDialog.Builder 项目背景色

android - AppCompatActivity 状态栏始终显示为黑色

android - 在 TextView CustomActionModeCallback 上选择溢出菜单项