Nice programing

Android : 현재 테마의 리소스 ID를 얻는 방법은 무엇입니까?

nicepro 2020. 12. 8. 20:00
반응형

Android : 현재 테마의 리소스 ID를 얻는 방법은 무엇입니까?


Android에서는 활동의 현재 테마 Resource.ThemegetTheme(). 또한에서와 같이 다른 테마의 리소스 ID를 통해 테마를 다른 테마로 설정할 수 있습니다 setTheme(R.style.Theme_MyTheme).

그러나 그만한 가치가 있는지 어떻게 알 수 있습니까? 현재 테마가 이미 설정하고 싶은 테마인지 여부는? 나는 다음과 같은 getTheme().getResourceId()것을 작성하기 위해, 같은 것을 찾고 있습니다 .

protected void onResume() {
    int newThemeId = loadNewTheme();
    if (newThemeId != getTheme().getResourceId()) { // !!!! How to do this?
        setTheme(newThemeId);
        // and rebuild the gui, which is expensive
    }
}

어떤 아이디어?


여기에 퍼즐 조각 하나가 있습니다 . AndroidManifest.xml에 설정된 기본 테마, context.getApplicationInfo().theme애플리케이션 수준에서 설정된 테마, 활동 내에서 해당 활동을 가져올 수 있습니다 getPackageManager().getActivityInfo(getComponentName(), 0).theme.

나는 그것이 우리에게 커스텀 getTheme()setTheme().

그래도 API를 사용 하는 것이 아니라 주변에서 일하는 것처럼 느껴집니다 . 그래서 누군가가 더 나은 아이디어를 생각해 냈는지보기 위해 질문을 열어 두겠습니다.

편집 : 있다

getPackageManager().getActivityInfo(getComponentName(), 0).getThemeResource()

활동이 재정의하지 않으면 자동으로 애플리케이션 테마로 대체됩니다.


리소스 ID를 얻지 않고 요구 사항을 해결하는 방법을 찾았습니다.

문자열 이름으로 각 테마에 항목을 추가하고 있습니다.

<item name="themeName">dark</item>

그리고 코드에서 다음과 같이 이름을 확인합니다.

TypedValue outValue = new TypedValue();
getTheme().resolveAttribute(R.attr.themeName, outValue, true);
if ("dark".equals(outValue.string)) {
   ...
}

반사를 통해이를 수행하는 방법이 있습니다. 이것을 당신의 활동에 넣으십시오.

int themeResId = 0;
try {
    Class<?> clazz = ContextThemeWrapper.class;
    Method method = clazz.getMethod("getThemeResId");
    method.setAccessible(true);
    themeResId = (Integer) method.invoke(this);
} catch (NoSuchMethodException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (IllegalAccessException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (IllegalArgumentException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (InvocationTargetException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
}
// use themeResId ...

[비공개 API에 대한 면책 ​​조항 삽입]


소스 에 따르면 Activity.setTheme는 Activity.onCreate보다 먼저 호출되므로 Android에서 설정할 때 themeId를 저장할 수 있습니다.

public class MainActivity extends Activity {
    private int themeId;

    @Override
    public void setTheme(int themeId) {
        super.setTheme(themeId);
        this.themeId = themeId;
    }

    public int getThemeId() {
        return themeId;
    }
}

If you have specified android:theme="@style/SomeTheme" in the <activity/> element in your manifest, then you can get the resource ID of the activity's theme like this:

int themeResId;
try {
    PackageManager packageManager = getPackageManager();
    //ActivityInfo activityInfo = packageManager.getActivityInfo(getCallingActivity(), PackageManager.GET_META_DATA);
    ActivityInfo activityInfo = packageManager.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
    themeResId = activityInfo.theme;
}
catch(PackageManager.NameNotFoundException e) {
    Log.e(LOG_TAG, "Could not get themeResId for activity", e);
    themeResId = -1;
}

Don't forget, if you are going to then call setTheme(themeResId) in your activity's onCreate() method, you need to do it before you call setContentView(...).

참고URL : https://stackoverflow.com/questions/7267852/android-how-to-obtain-the-resource-id-of-the-current-theme

반응형