2017-01-26 12 views
7

Я знаю, что есть способ установить темы, определив в styles.xml и использовать его как тоКак изменить тему из другого ресурса приложения в Android?

setTheme(android.R.style.MyTheme); 

Однако, я хочу, чтобы получить темы из другого приложения, которые я разработал, а также. Я знаю имена ресурсов, и на самом деле я могу получить идентификатор темы с этим блоком кода;

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

Вы можете получить идентификатор ресурса из другого пакета, но эти ресурсы не существуют в вашем APK. Загрузка ресурсов с помощью 'PackageManager # getResourcesForApplication (String packageName)' должна работать на drawables, strings, bools и т. Д. Однако я не считаю, что возможно, и определенно не рекомендуется, загружать другую тему APK. –

+0

Хотя я могу получить drawables, строки, булевы из других ресурсов пакета, я также ожидаю получить темы. Почему невозможно? – 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, которые включают в себя некоторые темы (Темы включают фоновые изображения, звуки по умолчанию, значки приложений и т. Д.) Когда я открываю приложение для диспетчера тем, я могу получить чертежи и перечислить их из тем apk соответственно. Тем не менее, я также хочу изменить некоторые темы приложений (например, «Настройки»), когда меняю тему. (Я хочу установить основные цвета, цвета акцента и т. Д.). Кстати, я работаю над проектом AOSP, и я могу легко изменить код настроек. Все, что я хочу, это изменение темы настроек из одного из моих ресурсов приложения темы. – Berkay92

4

Как уже упоминалось в комментарии, вы можете получить доступ к ресурсам из других приложений, но использование другой темы приложения не будет работать.


Поскольку имея доказательство всегда хорошая вещь, давайте посмотрим на исходный код (я использовал API 24 источников)

Calling setTheme() на Activity будет вызывать initializeTheme() в ContextThemeWrapper родительский класс, который будет в конечном итоге вызова onApplyThemeResource(..), который в свою очередь будет пытаться загрузить фактические данные тематические ресурсы по телефону theme.applyStyle(resId, true)

После цепи через обертку Resources.Theme мы можем увидеть в ResourcesImpl.ThemeImpl следующее, ш здесь AssetManager называется загрузить стиль в тему:

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

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

Это где вы пытаетесь и не загружать иностранную тему с другого приложения.


Поскольку большинство методов, которые вы должны были бы использовать это статические вызовы или пакет локальных методов не кажется, что есть какой-нибудь способ добиться того, что вы хотите (например, применение или создание новой темы)

Даже если вы задержите AssetManager другого приложения, используя getAssets() по контексту there is no accessible method to create or apply themes.

Таким образом, единственный способ использовать ресурсы другого приложения - это добавить ресурсы к вашим.

+0

Как насчет sharedUserId? Если я поместил sharedUserId для приложения и подпишу с тем же сертификатом, что произойдет? Я пробовал, но не повезло. Может быть, я делаю что-то неправильно в коде – Berkay92

1

Вы видели это демо: Multiple Theme Material Design

Вы можете проверить это демо для изменения времени выполнения темы.

Надеюсь, это поможет вам.

+0

Заданный вопрос изменить тему из другого пакета, установленного на устройстве. Это изменяет тему приложения как предопределено в стилях текущего пакета. Хотя это рекомендуемый способ применения тем, он не отвечает на вопрос OP. –

 Смежные вопросы

  • Нет связанных вопросов^_^