Change AppBarLayout theme programmatically?

2019-07-22 05:02发布

问题:

I have an AppBarLayout defined as such

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

However, sometimes I change the theme for the application and I also want to change it, and its children's. I have been partially successful by doing this:

    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
    appBarLayout.getContext().setTheme(R.style.AppTheme_Dark_AppBarOverlay);
    appBarLayout.invalidate();

However, the TextView for the title is not getting the theme settings.

How can I set it?

回答1:

From the documentation for Context.setTheme():

Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling setContentView(View) or inflate(int, ViewGroup)).

The bottom line is that setting the theme on a Context affects views that are created later. This means you'll have to rebuild your layout after setTheme().



回答2:

The solution to this was to use a ViewStub (http://developer.android.com/reference/android/view/ViewStub.html) that held two versions of my AppBarLayout: Light and Dark.

Then in onCreate I checked which theme was being loaded and replaced the ViewStub with the correct R.layout. I don't know why this is so difficult, or why you can't change the 'theme' for sub-views when you change the theme for the entire Activity, it's really perplexing.

In any case, this was the only solution that worked for me.