[android] Android Lollipop에서 _really_ 프로그래밍 방식으로 기본 및 악센트 색상을 변경하는 방법은 무엇입니까?

우선, 이 질문 은 매우 비슷한 질문을합니다. 그러나 내 질문에는 미묘한 차이가 있습니다.

내가 알고 싶은 것은 프로그래밍 방식 colorPrimary으로 테마 의 속성을 임의의 색상으로 변경할 수 있는지 여부 입니다.

예를 들어, 우리는 :

<style name="AppTheme" parent="android:Theme.Material.Light">
    <item name="android:colorPrimary">#ff0000</item>
    <item name="android:colorAccent">#ff0000</item>
</style>

런타임시 사용자는 #ccffff기본 색상 으로 사용하기 로 결정 합니다. 물론 가능한 모든 색상에 대한 테마를 만들 수있는 방법은 없습니다.

공개 SDK를 사용하여 작동하는 한 Android의 개인 내부 정보에 의존하는 것과 같은 해킹 된 작업을 수행 해야하는지 상관하지 않습니다.

내 목표는 결국하는 것입니다 ActionBar A는 같은 모든 위젯 CheckBox이 원색을 사용합니다.



답변

테마는 변경할 수 없습니다.


답변

연락처 앱에 대한 의견과 각 연락처에 테마를 사용하는 방법을 읽었습니다.

아마도 연락처 앱에는 몇 가지 사전 정의 된 테마가 있습니다 ( http://www.google.com/design/spec/style/color.html ).

onCreate 메소드에서 setContentView 메소드 앞에 테마를 적용 할 수 있습니다.

그런 다음 연락처 앱은 각 사용자에게 테마를 무작위로 적용 할 수 있습니다.

이 방법은 다음과 같습니다

setTheme(R.style.MyRandomTheme);

그러나이 방법에는 문제가 있습니다. 예를 들어 툴바 색상, 스크롤 효과 색상, 잔물결 색상 등을 변경할 수 있지만 상태 표시 줄 색상과 탐색 막대 색상을 변경할 수는 없습니다 (변경하려는 경우).

그런 다음이 문제를 해결하기 위해 이전과 다음 방법을 사용할 수 있습니다.

if (Build.VERSION.SDK_INT >= 21) {
        getWindow().setNavigationBarColor(getResources().getColor(R.color.md_red_500));
        getWindow().setStatusBarColor(getResources().getColor(R.color.md_red_700));
    }

이 두 가지 방법은 탐색 및 상태 표시 줄 색상을 변경합니다. 탐색 막대를 반투명으로 설정하면 색상을 변경할 수 없습니다.

마지막 코드 여야합니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setTheme(R.style.MyRandomTheme);
    if (Build.VERSION.SDK_INT >= 21) {
        getWindow().setNavigationBarColor(getResources().getColor(R.color.myrandomcolor1));
        getWindow().setStatusBarColor(getResources().getColor(R.color.myrandomcolor2));
    }
    setContentView(R.layout.activity_main);

}

스위치를 사용하고 임의의 숫자를 생성하여 임의의 테마를 사용하거나 연락처 앱에서와 같이 각 연락처에는 미리 정의 된 번호가있을 수 있습니다.

테마 샘플 :

<style name="MyRandomTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/myrandomcolor1</item>
    <item name="colorPrimaryDark">@color/myrandomcolor2</item>
    <item name="android:navigationBarColor">@color/myrandomcolor1</item>
</style>

내 영어가 유감입니다.


답변

Theme.applyStyle 을 사용 하여 다른 스타일을 적용하여 런타임에 테마를 수정할 수 있습니다 .

이 스타일 정의가 있다고 가정 해 봅시다.

<style name="DefaultTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/md_lime_500</item>
    <item name="colorPrimaryDark">@color/md_lime_700</item>
    <item name="colorAccent">@color/md_amber_A400</item>
</style>

<style name="OverlayPrimaryColorRed">
    <item name="colorPrimary">@color/md_red_500</item>
    <item name="colorPrimaryDark">@color/md_red_700</item>
</style>

<style name="OverlayPrimaryColorGreen">
    <item name="colorPrimary">@color/md_green_500</item>
    <item name="colorPrimaryDark">@color/md_green_700</item>
</style>

<style name="OverlayPrimaryColorBlue">
    <item name="colorPrimary">@color/md_blue_500</item>
    <item name="colorPrimaryDark">@color/md_blue_700</item>
</style>

이제 런타임에 테마를 다음과 같이 패치 할 수 있습니다.

getTheme().applyStyle(R.style.OverlayPrimaryColorGreen, true);

applyStyle레이아웃이 팽창하기 전에 메소드 를 호출해야합니다! 따라서보기를 수동으로로드하지 않으면 setContentView활동을 호출하기 전에 테마에 스타일을 적용 해야합니다.

물론 이것은 임의의 색상, 즉 1600 만 (256 3 ) 색상 중 하나를 지정하는 데 사용할 수 없습니다 . 그러나 스타일 정의와 Java 코드를 생성하는 작은 프로그램을 작성하면 512 (8 3 ) 중 하나와 같은 것이 가능해야합니다.

흥미로운 점은 테마의 여러 ​​측면에 서로 다른 스타일 오버레이를 사용할 수 있다는 것입니다. colorAccent예를 들어 몇 가지 오버레이 정의를 추가하십시오 . 이제 기본 색상과 악센트 색상에 대한 다양한 값을 거의 임의로 조합 할 수 있습니다 .

오버레이 테마 정의가 실수로 상위 스타일 정의에서 여러 스타일 정의를 상속하지 않도록해야합니다. 예를 들어, 스타일이라는 AppTheme.OverlayRed암시 적 스타일은 정의 된 모든 스타일을 상속 AppTheme하며 마스터 테마를 패치 할 때 이러한 모든 정의도 적용됩니다. 따라서 오버레이 테마 이름에서 점을 피하거나 비슷한 것을 사용 하고 빈 스타일로 Overlay.Red정의하십시오 Overlay.


답변

나는 모든 색 테마를 만들기 위해 몇 가지 해결책을 만들었습니다. 어쩌면 이것은 누군가에게 유용 할 수 있습니다. API 9 이상

1. 먼저 ” res / values-v9 / “를 생성 하고이 파일을 넣으십시오 : styles.xml
및 일반 “res / values”폴더가 스타일과 함께 사용됩니다.

2. 이 코드를 res / values ​​/ styles.xml에 넣으십시오.

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">#000</item>
        <item name="colorPrimaryDark">#000</item>
        <item name="colorAccent">#000</item>
        <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    </style>

    <style name="AppThemeDarkActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">#000</item>
        <item name="colorPrimaryDark">#000</item>
        <item name="colorAccent">#000</item>
        <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    </style>

    <style name="WindowAnimationTransition">
        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
    </style>
</resources>

3. AndroidManifest에 :

<application android:theme="@style/AppThemeDarkActionBar">

4. 이름이 “ThemeColors.java”인 새 클래스를 작성하십시오.

public class ThemeColors {

    private static final String NAME = "ThemeColors", KEY = "color";

    @ColorInt
    public int color;

    public ThemeColors(Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
        String stringColor = sharedPreferences.getString(KEY, "004bff");
        color = Color.parseColor("#" + stringColor);

        if (isLightActionBar()) context.setTheme(R.style.AppTheme);
        context.setTheme(context.getResources().getIdentifier("T_" + stringColor, "style", context.getPackageName()));
    }

    public static void setNewThemeColor(Activity activity, int red, int green, int blue) {
        int colorStep = 15;
        red = Math.round(red / colorStep) * colorStep;
        green = Math.round(green / colorStep) * colorStep;
        blue = Math.round(blue / colorStep) * colorStep;

        String stringColor = Integer.toHexString(Color.rgb(red, green, blue)).substring(2);
        SharedPreferences.Editor editor = activity.getSharedPreferences(NAME, Context.MODE_PRIVATE).edit();
        editor.putString(KEY, stringColor);
        editor.apply();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) activity.recreate();
        else {
            Intent i = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName());
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            activity.startActivity(i);
        }
    }

    private boolean isLightActionBar() {// Checking if title text color will be black
        int rgb = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
        return rgb > 210;
    }
}

5. 주요 활동 :

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new ThemeColors(this);
        setContentView(R.layout.activity_main);
    }

    public void buttonClick(View view){
        int red= new Random().nextInt(255);
        int green= new Random().nextInt(255);
        int blue= new Random().nextInt(255);
        ThemeColors.setNewThemeColor(MainActivity.this, red, green, blue);
    }
}

색상을 변경하려면 Random을 RGB로 바꾸면 도움이되기를 바랍니다.

여기에 이미지 설명을 입력하십시오

완전한 예가 있습니다 : ColorTest.zip


답변

Dahnark의 코드를 사용했지만 ToolBar 배경도 변경해야합니다.

if (dark_ui) {
    this.setTheme(R.style.Theme_Dark);

    if (Build.VERSION.SDK_INT >= 21) {
        getWindow().setNavigationBarColor(getResources().getColor(R.color.Theme_Dark_primary));
        getWindow().setStatusBarColor(getResources().getColor(R.color.Theme_Dark_primary_dark));
    }
} else {
    this.setTheme(R.style.Theme_Light);
}

setContentView(R.layout.activity_main);

toolbar = (Toolbar) findViewById(R.id.app_bar);

if(dark_ui) {
    toolbar.setBackgroundColor(getResources().getColor(R.color.Theme_Dark_primary));
}


답변

colorPrimary의 색상을 변경할 수는 없지만 다른 colorPrimary 색상으로 새 스타일을 추가하여 응용 프로그램의 테마를 변경할 수 있습니다

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
</style>

<style name="AppTheme.NewTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorOne</item>
    <item name="colorPrimaryDark">@color/colorOneDark</item>
</style>

활동 세트 테마 내부

 setTheme(R.style.AppTheme_NewTheme);
 setContentView(R.layout.activity_main);


답변

당신이 할 수있는 활동에서 :

getWindow().setStatusBarColor(i color);