colorPrimary и colorPrimaryDark игнорируются в теме приложения

(Примечание. Это в некоторой степени связано с при использовании ActionMode, строка состояния становится черной на Lollipop, так что там может быть какая-то дополнительная информация, которую я случайно пропустил в этом вопросе)

У меня определена следующая тема:

<style name="Material" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/app_green</item>
    <item name="colorPrimaryDark">@color/app_green_dark</item>

    <item name="android:textColorPrimary">@color/action_bar_text</item>
    <item name="android:textColor">@color/secondary_text_color</item>
    <item name="android:color">@color/secondary_text_color</item>

    <item name="colorAccent">@color/app_green</item>
    <item name="android:editTextColor">@color/secondary_text_color</item>

    <item name="textHeaderMaxLines">@integer/text_header_max_lines</item>
    <item name="trackAbstractMaxLines">@integer/track_abstract_max_lines</item>
    <item name="activatableItemBackground">@drawable/activatable_item_background</item>

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

    <!-- Global UI Assignments -->
    <item name="android:spinnerStyle">@style/Material.Widget.Spinner</item>

    <item name="android:buttonStyle">@style/Material.Widget.Button</item>
    <item name="android:checkboxStyle">@style/Material.Widget.Checkbox</item>
    <item name="android:textAppearance">@android:style/TextAppearance</item>

    <item name="android:popupWindowStyle">@style/Material.Window.Popup</item>

    <!-- ViewPager -->
    <item name="vpiCirclePageIndicatorStyle">@style/Material.Activity.Login.ViewPagerIndicator.CustomCircle</item>
    <item name="buttonBarStyle">?android:buttonBarStyle</item>
    <item name="buttonBarButtonStyle">?android:buttonBarButtonStyle</item>
    <item name="indeterminateProgressStyle">?android:indeterminateProgressStyle</item>

    <!-- API 14+ (compatibility) -->
    <item name="listPreferredItemPaddingLeft">@dimen/compat_list_preferred_item_padding_left</item>
    <item name="listPreferredItemPaddingRight">@dimen/compat_list_preferred_item_padding_right</item>
    <item name="listPreferredItemHeightSmall">@dimen/compat_list_preferred_item_height_small</item>
</style>

Я использую эту тему следующим образом:

<application
    android:name=".MyApp"
    android:icon="@drawable/icon"
    android:logo="@null"
    android:label="@string/app_name"
    android:theme="@style/Material"
    android:hardwareAccelerated="true"
    android:allowBackup="true">
    <activity
        android:name=".ui.MainActivity"
        android:label="@string/title_activity_main">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.DetailActivity"
        android:label="Details"
        android:theme="@style/Material.Activity" >
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable"/>
    </activity>
</application>

Вся моя деятельность происходит от NavigationDrawerActivity:

/**
 * 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);
      }  
    }

В NavigationDrawerActivity мне фактически приходится вручную устанавливать цвет фона строки состояния (см. вторую строку setupNavigationDrawer()), а не автоматически устанавливать его из colorPrimaryDark на устройствах Android 5.0. Кроме того, изменение цвета в colorPrimary или colorPrimaryDark не меняет цвет строки состояния (хотя это может быть следствием установки windowTranslucentStatus на true) или цвета фона Toolbar.

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


person jwir3    schedule 26.05.2015    source источник
comment
Я получил эту идею от: developer.android.com/training/material/theme. html#StatusBar, что заставило меня подумать, что строка состояния будет окрашена colorPrimaryDark.   -  person jwir3    schedule 26.05.2015


Ответы (1)


Документация, которую вы цитируете, относится к родному Android 5.0 Theme.Material. appcompat-v7, похоже, не применяет автоматически какие-либо цвета к строке состояния, по крайней мере, в настоящее время.

Так, например, этот образец проекта при запуске на Устройство Android 5.0 получает цвет строки состояния, поскольку использует Theme.Material. Этот порт того же примера проекта использовать appcompat-v7 нельзя. пересмотренная версия того же образца, в котором используется appcompat-v7 и специально запрашивается изменение цвета строки состояния получает цвет.

person CommonsWare    schedule 26.05.2015
comment
Таким образом, при использовании панели навигации этот автоматический стиль совсем не будет работать, так как вам нужно получить его из темы AppCompat? - person jwir3; 26.05.2015
comment
См. stackoverflow.com/questions/22301924/ для справки о том, что я имею в виду - person jwir3; 26.05.2015
comment
@jwir3: вам не нужно использовать appcompat-v7 для использования панели навигации. DrawerLayout сам работает с любой активностью. Исходный ActionBarDrawerToggle, который работал с собственной панелью действий, устарел, и для замены требуется appcompat-v7. Поэтому, если вы хотите использовать официальный, не устаревший переключатель, вам нужно использовать appcompat-v7, что означает, что вы должны сами установить цвет строки состояния. Лично я бы клонировал appcompat-v7 ActionBarDrawerToggle и портировал его для работы с собственной панелью действий, как я сделал с MediaRouteActionProvider, но это только я. :-) - person CommonsWare; 26.05.2015