How to change theme from another app resource in android?

做~自己de王妃 提交于 2019-12-10 04:04:56

问题


I know there is a way to set themes by defining in styles.xml and use it like that

setTheme(android.R.style.MyTheme);

However, I want to get themes from another app which I developed as well. I know the resources names and actually I am able to get theme id with this code block;

Resources res = getPackageManager().getResourcesForApplication("com.example.theme");
int resThemeId = res.getIdentifier("my_theme","style","com.example.theme");

When I debug, I see that resThemeId is not zero.

Then, I need the final command to set this theme. Before super.onCreate() function, I try to implement this method but it seems it is not working

setTheme(resThemeId);

But instead of this, if I write below statement, I works fine

setTheme(android.R.style.Theme_Holo_Light);

So, what should I do to use a theme from different package resource?


回答1:


So, what should I do to use a theme from different package resource?

You shouldn't do this for many reasons. I wrote a simple project that shows that it is indeed possible as long as the package contains the resources your activity uses.

See: https://github.com/jaredrummler/SO-41872033


Basically, you would need to return the package's resources from the activity:

public class MainActivity extends AppCompatActivity {

  Resources resources;

  @Override protected void onCreate(Bundle savedInstanceState) {

    int themeResId = getResources().getIdentifier("AppTheme", "style", "com.example.theme");
    if (themeResId != 0) {
      setTheme(themeResId);
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override public Resources getResources() {
    if (resources == null) {
      try {
        resources = getPackageManager().getResourcesForApplication("com.example.theme");
      } catch (PackageManager.NameNotFoundException e) {
        resources = super.getResources();
      }
    }
    return resources;
  }

}

This is just to show that it is possible. Again, I recommend that you avoid this.




回答2:


As already mentioned in a comment you can access resources from other applications, but using another applications theme will not work.


Since having proof is always a good thing let's have a look at the source code (I used API 24 sources)

Calling setTheme() on an Activity will invoke initializeTheme() in the ContextThemeWrapper parent class, which will end up calling onApplyThemeResource(..) which in turn will try to load the actual theme data from resources by calling theme.applyStyle(resId, true)

Following the chain through the wrapper Resources.Theme we can see in ResourcesImpl.ThemeImpl the following, where AssetManager is called to load the style into the theme:

void applyStyle(int resId, boolean force) {
    synchronized (mKey) {
        AssetManager.applyThemeStyle(mTheme, resId, force);

        mThemeResId = resId;
        mKey.append(resId, force);
    }
}

This is where you try and fail to load the foreign theme from your other app.


Since most of the methods you would need to use are static calls or package local methods it does not seem that there is any way to achieve what you want, (e.g. applying or creating a new Theme)

Even if you get a hold of the other application's AssetManager by using getAssets() on a context there is no accessible method to create or apply themes.

So the only way to use another app's resources would be to add the resources to yours.




回答3:


Have you seen this demo: Multiple Theme Material Design

You can check this demo for runtime theme change.

Hope it will helps you.



来源:https://stackoverflow.com/questions/41872033/how-to-change-theme-from-another-app-resource-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!