2017-01-26 64 views
7

我知道有在styles.xml定義設置主題和使用它像如何從android中的另一個應用程序資源更改主題?

setTheme(android.R.style.MyTheme); 

不過,我想從另一個應用程序,我開發以及獲得主題的方式。我知道資源名稱,實際上我能夠使用此代碼塊獲取主題ID;

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

當我調試時,我看到resThemeId不是零。

然後,我需要最後的命令來設置這個主題。 super.onCreate()函數之前,我嘗試實施這種方法,但現在看來,這是行不通的

setTheme(resThemeId); 

但不是這個,如果我寫下面的語句,我工作得很好

setTheme(android.R.style.Theme_Holo_Light); 

所以,我該怎麼做才能使用來自不同包資源的主題?

+3

您可以從另一個軟件包獲取資源ID,但這些資源在您的APK中不存在。使用'PackageManager#getResourcesForApplication(String packageName)'加載資源應該適用於drawables,strings,bools等。但是,我不相信這是可能的,絕對不推薦加載其他APK的主題。 –

+0

雖然我可以從其他軟件包資源中獲取繪圖,字符串,布爾值,但我希望獲得主題。爲什麼不可能? – Berkay92

+0

這是可能的(見我的答案)。您需要重寫getResrouces以返回其他應用程序的資源,以便可以應用該主題。這也將返回來自其他應用程序的所有字符串,佈局,繪圖和其他資源,因此,不建議這樣做。 –

回答

3

那麼,我應該怎麼做才能使用不同包裝資源的主題?

您不應該這樣做,原因很多。我寫了一個簡單的項目,表明只要包中包含您的活動使用的資源,就可以實現。

請參見:https://github.com/jaredrummler/SO-41872033


基本上,你需要從活動返回程序包的資源:

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; 
    } 

} 

這只是表明它是可能的。同樣,我建議你避免這種情況。

+0

這樣可以在運行時更改資源嗎?我的意思是,我想從其他資源設置主題後設置原始資源? – Berkay92

+0

我不認爲這是可能的,但我也不認爲從其他軟件包應用主題是可能的。這就是爲什麼我不會推薦這個解決方案。您不希望將其他包的資源用於佈局和活動中的任何可繪製對象。你試圖用這個來達到什麼目的? –

+0

我其實嘗試寫一個主題管理器和不同的apk包含一些主題(主題包括背景圖像,默認聲音,應用程序圖標等)。當我打開主題管理器應用程序時,我可以檢索drawable並從主題apk中相應地列出它們。不過,我還想在更改主題時更改一些應用程序主題(如「設置」應用程序)。 (我想設置主要顏色等)順便說一下,我正在開發AOSP項目,並且可以輕鬆更改設置代碼。我只想從我的一個主題應用程序資源中更改設置主題。 – Berkay92

4

正如評論中已經提到的那樣,您可以從其他應用程序訪問資源,但使用其他應用程序主題將不起作用。


由於具有證明始終是一件好事,讓我們來看看源代碼(我用API 24個源)

Activity調用setTheme()將調用initializeTheme()ContextThemeWrapper父類,這將最終調用onApplyThemeResource(..)這反過來將嘗試通過調用theme.applyStyle(resId, true)

繼通過包裝Resources.Theme鏈,我們可以在ResourcesImpl.ThemeImpl看到以下加載從資源的實際主題數據w這裏AssetManager叫的風格裝入主題:

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

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

這是你嘗試,並無法從您的其他應用程序加載國外主題。


由於大多數的方法,您將需要使用的都是靜態的電話或封裝本地方法似乎不存在任何方式來實現你想要的,(如應用或創建一個新的主題)

即使您通過在上下文there is no accessible method to create or apply themes上使用getAssets()獲得其他應用程序的AssetManager的保留。

因此,使用其他應用資源的唯一方法是將資源添加到您的資源。

+0

sharedUserId怎麼樣?如果我將sharedUserId用於應用程序並使用相同的證書籤名,會發生什麼情況?我試過但沒有運氣。也許我在代碼的某個地方做錯了 – Berkay92

1

你見過這個演示:Multiple Theme Material Design

您可以檢查此演示了運行時的主題變化。

希望它能幫助你。

+0

要求更改設備上安裝的其他軟件包的主題。這會將應用程序主題更改爲當前包的樣式中預定義的主題。雖然這是應用主題的推薦方式,但它並不回答OP的問題。 –

相關問題