web-dev-qa-db-ja.com

Android Lollipopでプログラムでプライマリカラーとアクセントカラーを_本当に_変更するにはどうすればいいですか?

まず第一に、 この質問 非常によく似た質問をします。しかし、私の質問には微妙な違いがあります。

私が知りたいのは、プログラムでテーマの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すべてのウィジェットにCheckBoxのようなウィジェットを使用することです。

142
nhaarman

テーマは不変です、できません。

167
Chris Banes

連絡先アプリに関するコメントと、各連絡先のテーマの使用方法を読みます。

おそらく、連絡先アプリにはいくつかの定義済みのテーマがあります(ここから各マテリアルの原色について: 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));
    }

この2つの方法は、ナビゲーションとステータスバーの色を変更します。ナビゲーションバーを半透明に設定した場合、その色を変更することはできません。

これが最終的なコードです。

@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>

私の英語ですみません。

61

あなたはそれに別のスタイルを適用することによって実行時にあなたのテーマを修正するために 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色)から1色を指定することはできません。3)色。しかし、あなたがあなたのためにスタイル定義とJavaコードを生成する小さなプログラムを書くならば、512のうちの1のような何か(83)可能であるべきです。

これが面白いのは、テーマのさまざまな側面にさまざまなスタイルのオーバーレイを使用できることです。たとえばcolorAccentにいくつかのオーバーレイ定義を追加するだけです。これで、原色とアクセントカラーに異なる値を組み合わせることができます ほとんど 勝手に。

オーバーレイのテーマ定義が誤って親スタイル定義から多数のスタイル定義を継承しないようにする必要があります。たとえばAppTheme.OverlayRedというスタイルは、AppThemeで定義されているすべてのスタイルを暗黙的に継承します。マスターテーマにパッチを適用すると、これらすべての定義も適用されます。そのため、オーバーレイのテーマ名にドットを使用しないようにするか、Overlay.Redのようなものを使用してOverlayを空のスタイルとして定義します。

42
devconsole

私は任意の色のテーマを作るためにいくつかの解決策を作成しました、多分これは誰かにとって役に立つかもしれません。 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。を呼び出す前setContentView(R.layout.activity_main)追加するだけです:

new ThemeColors(this);

色を変更するには、RandomをあなたのRGBに置き換えます。

    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            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);
        }
    });

enter image description here

17
IQ.feature

Dahnarkのコードを使用しましたが、ツールバーの背景も変更する必要があります。

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));
}
3
lgallard

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);
1
varghesekutty