Search code examples
androidtoolbarandroid-themeandroid-statusbar

(android) Why does the style of the theme only partially apply?


I want to know why the theme's style is only partially applied.

I set the basic theme as NoActionBar.

And I made a new toolbar using CoordinatorLayout, AppBarLayout, and Toolbar in Main.xml.

I also defined New theme style for this toolbar and changed stauts bar color and applied this theme.

But it doesn't work. However, when i changed stauts bar color defined in BaseTheme.

It worked well. I'm so confused.

I clearly applied the theme style I defined. But the BaseTheme's status bar color still applies.

When i changed Toolbar color, It was applied well.

I don't know the reason.

Was the My Custom Toolbar affected by `Manifest's Theme'?

Please tell me why..

Main.xml

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent">
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:elevation="0dp"
            android:theme="@style/Theme.AppBarOverlay">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:titleTextColor="@color/black"
                app:titleMarginStart="30dp"
                android:paddingRight="30dp"
                android:theme="@style/Theme.PopupOverlay"/>
        </com.google.android.material.appbar.AppBarLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.WriteWeight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>

    <style name="Theme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" >
        <item name="colorPrimary">@color/light_green</item>

        <item name="android:statusBarColor" tools:targetApi="l">@color/light_green_dark</item> <!-- not apply -->
<!--        <item name="colorPrimaryVariant">@color/light_green_dark</item> ///////////////// not apply -->
<!--        <item name="colorPrimaryDark">@color/light_green_dark</item>    ///////////////// not apply -->
    </style>

    <style name="Theme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">
        <item name="colorPrimary">@color/light_green</item>
        <item name="colorPrimaryVariant">@color/light_green_dark</item>
        <item name="colorPrimaryDark">@color/light_green_dark</item>
    </style>
</resources>

Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.writeweight">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.WriteWeight">
        <activity android:name=".data.DailyRecordDetailActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    RecyclerView rcv_dailyRecord;
    Toolbar toolbar;
    LinearLayoutManager layoutManager;

    DailyRecordAdapter dailyRecordAdapter;
    ArrayList<DailyRecordModel> dailRecordItems;

    final static String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rcv_dailyRecord = findViewById(R.id.rcv_dailyrecord);
        toolbar = findViewById(R.id.toolbar);
        
        setSupportActionBar(toolbar);
//        getSupportActionBar().setDisplayShowTitleEnabled(false);
//        toolbar.setTitle("목 록");


Solution

  • You created a customized Theme.AppBarOverlay style in styles.xml. Now this style is useless unless you apply it to a certain view/widget.

    The first point:

    Applying a style to a particular view, doesn't affect other views/widgets.

    Looking at your layout to see which view you set this style to: it's the AppBarLayout widget.

    the AppBarLayout area doesn't include the status bar area, that is because the status bar is android system component, not activity widget (not part of your activity). So, when applying this style to AppBarLayout, it can only apply the attributes of this style on the area that this AppBarLayout view occupies on your screen.

    The second point:

    Each view/widget has certain attributes that can affect its style; not only there are common attributes that can be applied to any view; but also there are other unique attributes that are specific to certain views. Applying style attributes to views that can't utilize them won't have affect on those views, or they can have unexpected behavior on those views.

    Applying both points in your example:

    You used android:statusBarColor attribute which can be applied to system/status bar, and added it to the style that is applied to AppBarLayout; so this style can only be applied to the AppBarLayout surrounding area, i.e. not the status bar itself (point 1), and also the AppBarLayout won't utilize it as it won't affect anything in its layout because it's not a part of attributes that can affect AppBarLayout (point 2).

    The status bar is a system component, not app/activity component/widget, so changing it must be in the global theme of your app, or you can change it programmatically.

    You can have a look at here for more info.