【问题标题】:setTheme not changing the theme colorssetTheme 不改变主题颜色
【发布时间】:2017-01-10 17:43:08
【问题描述】:

我知道这个问题被问过几次。但我找不到我的问题。 我想更改应用程序的主题,但我的 colorPrimary 、 colorAccent 等......没有改变。

我的 MainActivity 扩展了 BasicActivity。它看起来像这样:

public class MainActivity extends BasicActivity {
    public static String MY_PREFS = "MY_PREFS";
    private SharedPreferences mySharedPreferences;
    int prefMode = Activity.MODE_PRIVATE;

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ViewPagerAdapter adapter;
    private TextView tabOne, tabTwo, tabThree;

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

}
}

这是我的 BasicActivity(在这种情况下,我更简单地表明主题取自 R.style):

public class BasicActivity extends AppCompatActivity {

    public static String MY_PREFS = "MY_PREFS";
    int prefMode = Activity.MODE_PRIVATE;



    protected void onCreate(Bundle savedInstanceState) {


        JsonParser parser = new JsonParser(getApplicationContext());

        int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
        setTheme(R.style.c_2ecc71_BC6C2B);


        if (android.os.Build.VERSION.SDK_INT >= 19) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        }

        super.onCreate(savedInstanceState);

    }

}

还有我的 XML:

<style name="c_2ecc71_BC6C2B" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">#2ecc71</item>
    <item name="colorPrimaryDark">#1ebc61</item>
    <item name="colorAccent">#BC6C2B</item>
</style>

根据前面的问题,这段代码应该可以工作,但在我的情况下,即使我在调用 setContentView(R.layout.activity_main); 之前设置了主题,在其 XML 中具有 colorPrimary 的视图仍会加载旧主题的颜色,但仍会加载新主题的颜色

谢谢!

【问题讨论】:

  • 您已经在 BaseActivity 中硬编码了主题,而不是获取引用资源 ID。你需要把 setTheme(value_from_resourceId); BaseActivity 总是调用 setTheme(R.style.c_2ecc71_BC6C2B);比运行时值

标签: android themes


【解决方案1】:

如果你使用 Fragments,它们会忽略你在 onCreate() 中设置的值,如果你覆盖 getTheme() 方法,它也会在 Fragments 中使用:

回答了不同的问题:Change Activity's theme programmatically

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    theme.applyStyle(R.style.c_2ecc71_BC6C2B, true);
    return theme;
}

在 MainActivity 或 BasicActivity 中使用它,具体取决于您希望它应用的位置。您将不再需要在 onCreate 中更改它。

【讨论】:

  • 这正是我所需要的
【解决方案2】:

您正在尝试扩展 Android 的较新主题之一(高于 API 21)。除了上面所有的答案,你可以把你的主题放在styles.xml(v21)中。

更多信息在这里https://developer.android.com/training/material/compatibility.html

【讨论】:

    【解决方案3】:

    不确定你是否真的想以编程方式设置它,但你可以试试这个:How to setTheme to an activity at runtime? It doesn't work call setTheme before onCreate and setContentView

    如果您希望为整个应用程序设置它,那么在 AndroidManifest.xml 文件中设置它可能会更容易/更干净。

    <application android:theme="@style/CustomTheme">
    

    另外,我会极力避免使用包含值的样式名称。使用样式的目的是避免对值进行硬编码,并允许它们可配置和可重用。如果你想改变colorPrimary,你是否也要改变你的样式名称?

    【讨论】:

    • 我希望能够在运行时动态更改它
    • 是的,这就是答案中的第一个链接所解释的。您应该可以像以下代码一样执行此操作: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Translucent_NoTitleBar); // 这里设置 setContentView(...) }
    【解决方案4】:

    要在运行时设置主题,您可以使用以下代码行:

    setTheme(android.R.style.Theme_Name);

    并在 onCreate() 方法中调用 setContentView() 和 super.onCreate() 方法之前编写。

    【讨论】:

      【解决方案5】:

      如果你想在运行时改变那种东西,你必须插入所有那些“setTheme(android.R.style.Theme_Name);” runonUiThread 中的方法,如下所示:

      public class BasicActivity extends AppCompatActivity {
      
      public static String MY_PREFS = "MY_PREFS";
      int prefMode = Activity.MODE_PRIVATE;
      
      
      
      protected void onCreate(Bundle savedInstanceState) {
      
      
          JsonParser parser = new JsonParser(getApplicationContext());
      
          int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
      
          runOnUiThread(new Runnable() {
      
                          @Override
                          public void run() {
      
                           setTheme(R.style.c_2ecc71_BC6C2B);
                          }
                      });
      
          recreate();
          if (android.os.Build.VERSION.SDK_INT >= 19) {
              getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
      
          }
      
          super.onCreate(savedInstanceState);
      
      }
      
      }
      

      然后调用 recreate() !

      根据 Android -

      void 重新创建 () 导致使用新实例重新创建此 Activity。这导致与由于配置更改而创建 Activity 时的流程基本相同——当前实例将经历其生命周期到 onDestroy() 并在其后创建一个新实例。

      【讨论】:

        【解决方案6】:

        只需如下所示修改您的 BasicActivity 和 MainActivity 并创建适当的主题。您可以在应用启动期间使用共享偏好来检查主题状态。

        基本活动.java

        public abstract class BasicActivity extends AppCompatActivity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        
            try {
                if (getLayoutID() != 0) {
                    setContentView(getLayoutID());
                }
            } catch (Exception ex) { /* ... */ }
        
            final boolean THEME_DARK = true;// read appropriate value from SP or any other storage
        
            Toolbar toolbar;
            if ((toolbar = getToolbar()) != null) {
                if (THEME_DARK/*  check theme type here*/) {
                    toolbar.setPopupTheme(R.style.c_2ecc71_BC6C2B);
                }
                try {
                    setSupportActionBar(toolbar);
                } catch (NoClassDefFoundError e) {
                    // Toast
                    finish();
                }
            }
        
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Window window = getWindow();
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
            }
        }
        
        public abstract Toolbar getToolbar();
        
        public abstract int getLayoutID();
        
        }     
        

        MainActivity.java

            public class MainActivity extends BasicActivity {
        
            private Toolbar toolbar;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
            }
        
            @Override
            public Toolbar getToolbar() {
                return toolbar == null ? toolbar = (Toolbar) findViewById(R.id.toolbar) : toolbar;
            }
        
            @Override
            public int getLayoutID() {
                return R.layout.activity_main;
            }
           }
        

        【讨论】:

          【解决方案7】:

          您已将主题硬编码在 BaseActivity 中,而不是获取目标资源 ID。

          你需要把setTheme(value_from_resourceId);

          目前 BaseActivity 总是调用而不管你解析的值是什么

          setTheme(R.style.c_2ecc71_BC6C2B);
          

          比引用运行时值

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-03
            • 1970-01-01
            • 1970-01-01
            • 2019-03-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-19
            相关资源
            最近更新 更多