2017-01-26 2 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가 0이 아닙니다.

그런 다음이 테마를 설정하는 마지막 명령이 필요합니다. 나는 문 아래 작성하는 경우 super.onCreate() 함수 전에, 나는이 방법을 구현하려고하지만하지만 그 대신이의

setTheme(resThemeId); 

를 작동하지 않는 것, 내가 잘 작동

setTheme(android.R.style.Theme_Holo_Light); 

그래서 , 다른 패키지 리소스의 테마를 사용하려면 어떻게해야합니까?

+3

다른 패키지에서 리소스 ID를 가져올 수 있지만 해당 리소스는 APK에 없습니다. 'PackageManager # getResourcesForApplication (String packageName) '을 사용하여 리소스를로드하는 것은 드로어 블, 문자열, 부울 등에서 작동해야합니다. 그러나 다른 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; 
    } 

} 

이 그것이 가능하다는 것을 보여주기 위해 단지이다. 다시 말하지만, 이것을 피하는 것이 좋습니다. Multiple Theme Material Design

당신은 런타임 테마 변경이 데모를 확인할 수 있습니다

+0

이런 식으로 런타임에 리소스를 변경할 수 있습니까? 다른 리소스의 테마를 설정 한 후에 원래의 리소스를 설정하고 싶습니다. – Berkay92

+0

가능하다고 생각하지 않지만 다른 패키지에서 테마를 적용하는 것이 가능하다고 생각하지 않았습니다. 그래서이 솔루션을 권장하지 않습니다. 레이아웃 및 액티비티의 드로어 블에 다른 패키지의 리소스를 사용하고 싶지는 않습니다. 이것으로 정확히 무엇을 달성하려고합니까? –

+0

실제로 테마 관리자와 다른 apk를 작성하려고합니다. 테마에는 배경 이미지, 기본 사운드, 앱 아이콘 등이 포함되어 있습니다. 테마 관리자 앱을 열면 드로어 블을 검색하고 이에 따라 APK 테마를 나열 할 수 있습니다. 그러나 테마를 변경하면 설정 앱과 같은 일부 애플리케이션 테마도 변경하고 싶습니다. (기본, 악센트 색상 등을 설정하고 싶습니다.) 그건 그렇고, 나는 AOSP 프로젝트를 진행하고 있으며 설정 코드를 쉽게 바꿀 수 있습니다. 내가 원하는 것은 내 테마 응용 프로그램 자원 중 하나에서 설정 테마를 변경하는 것입니다. – Berkay92

4

이미 주석에서 언급했듯이 다른 응용 프로그램의 자원에 액세스 할 수 있지만 다른 응용 프로그램 테마를 사용하면 작동하지 않습니다.


증거를 가지고 항상이기 때문에 좋은 일이의 소스 코드를 살펴 보자하는 것이라고 ContextThemeWrapper 부모 클래스에 initializeTheme()를 호출 할 것이다 ActivitysetTheme()를 호출

(I는 API (24) 소스를 사용) 승, 다시 우리가 ResourcesImpl.ThemeImpl에 다음을 볼 수있는 래퍼 Resources.Theme을 통해 체인에 따라 theme.applyStyle(resId, true)

를 호출하여 자원의 실제 테마 데이터를로드하려고 할 onApplyThemeResource(..)를 호출 결국 여기 AssetManager는 테마로 스타일을로드하기 위해 호출됩니다

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

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

당신이 시도하고 다른 응용 프로그램에서 외국 테마를로드에 실패 곳입니다. 당신이 당신이 원하는 것을 달성 할 수있는 방법이 있다는 것을하지 않는 것 로컬 방법이다 정적 호출을 사용하거나 포장 할 필요가 방법의 대부분 때문에


,

(예를 적용하거나 새로운 테마를 만드는)

문맥에 getAssets()을 사용하여 다른 응용 프로그램의 AssetManager을 보유하더라도 there is no accessible method to create or apply themes.

다른 앱의 리소스를 사용하는 유일한 방법은 귀하의 리소스를 추가하는 것입니다.

+0

sharedUserId는 어떻습니까? 응용 프로그램과 공유 인증서 모두에 대해 동일한 UUID를 넣으면 동일한 인증서가 사용됩니다. 나는 시도했다. 그러나 어떤 운도. 어쩌면 내가 코드 어딘가에서 잘못하고있다. – Berkay92

1

는이 데모를 보았다.

희망은 도움이 될 것입니다.

+0

질문은 장치에 설치된 다른 패키지에서 테마를 변경하도록 요청했습니다. 이렇게하면 현재 패키지의 스타일에서 미리 정의 된대로 앱 테마가 변경됩니다. 이것은 테마를 적용하는 데 권장되는 방법이지만 OP의 질문에는 대답하지 않습니다. –

관련 문제