プログラムでAndroid図形の色を設定する


168

質問をよりシンプルにするために編集しています。これが正確な回答に役立つことを期待しています。

私が次のようなoval形をしているとしましょう:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:angle="270"
           android:color="#FFFF0000"/>
    <stroke android:width="3dp"
            android:color="#FFAA0055"/>
</shape>

アクティビティクラス内からプログラムで色を設定するにはどうすればよいですか?


このドローアブルを何に設定しますか?
Vikram 2013

ドローアブルはでovalあり、ImageViewの背景です。
Cote Mounyo 2013

この質問が難しすぎる場合、複数の画像をキャンバスに描画し、レイヤー化された最終製品をビューの背景として設定する方法はありますか?
Cote Mounyo 2013

これを実現するには、Viewクラスを拡張し、baseウィジェット(RelativeLayoutFrameLayout)のオーバーラップを許可するレイアウトのビューとして使用します。この拡張Viewクラス内では、次のことができdraw multiple images onto a canvasます。しかし、それを行う前に、これを見てください-> リンク(まだの場合)。
Vikram 2013

回答:


266

backgroundがのインスタンスであるシナリオをカバーするように回答が更新されましたColorDrawable。これを指摘してくれたTyler Pfaffに感謝します。

ドローアブルは楕円形で、ImageViewの背景です。

DrawableimageView使用してから取得getBackground()

Drawable background = imageView.getBackground();

通常の容疑者と照合します。

if (background instanceof ShapeDrawable) {
    // cast to 'ShapeDrawable'
    ShapeDrawable shapeDrawable = (ShapeDrawable) background;
    shapeDrawable.getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    // cast to 'GradientDrawable'
    GradientDrawable gradientDrawable = (GradientDrawable) background;
    gradientDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    // alpha value may need to be set again after this call
    ColorDrawable colorDrawable = (ColorDrawable) background;
    colorDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

コンパクトバージョン:

Drawable background = imageView.getBackground();
if (background instanceof ShapeDrawable) {
    ((ShapeDrawable)background).getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    ((GradientDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    ((ColorDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

nullチェックは必要ないことに注意してください。

ただし、mutate()他の場所で使用されている場合は、変更する前にドローアブルで使用する必要があります。(デフォルトでは、XMLからロードされたドローアブルは同じ状態を共有します。)


3
回答ありがとうございます。(+1)。コードに他のバグが発生しているため、テストが困難です。しかし、これでもsolid形状の一部が設定される可能性があります。そのstroke部分はどうですか?
Cote Mounyo 2013

1
@TiGer @username通知がユーザーに確実に送信されるように、コメントを追加する必要があります。ちなみに、ShapeDrawableストローク部分を設定するにはサブクラス化する必要があります。詳細はこちら:リンク。受け入れられた回答の問題について言及しているコメントを見てください。
Vikram 2013年

3
android.graphics.drawable.GradientDrawableをandroid.graphics.drawable.ShapeDrawableにキャストできないキャストが失敗する
John

3
@John ImageView's背景がに設定されているGradientDrawable場合、getBackground()は返されませんShapeDrawable。代わりに、使用GradientDrawable:返されたことをGradientDrawable gradientDrawable = (GradientDrawable)imageView.getBackground();...... gradientDrawable.setColors(new int[] { color1, color2 });
Vikram

2
おかげで..私の世界を救った。
sid_09 2016年

43

このようにしてください:

    ImageView imgIcon = findViewById(R.id.imgIcon);
    GradientDrawable backgroundGradient = (GradientDrawable)imgIcon.getBackground();
    backgroundGradient.setColor(getResources().getColor(R.color.yellow));

1
@ user3111850 呼び出す前にandroid:backgroundxmlまたはsetBackgroundアクティビティに追加しましたgetBackground()か?あなたがそうしたなら、それはうまくいくはずです。
Lee Yi Hong

41

最近のより簡単な解決策は、形状を背景として使用し、プログラムで色を変更することです。

view.background.setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_ATOP)

使用可能なオプションについては、PorterDuff.Modeを参照してください。

更新(API 29):

上記のメソッドはAPI 29以降廃止され、次のように置き換えられます。

view.background.colorFilter = BlendModeColorFilter(Color.parseColor("#343434"), BlendMode.SRC_ATOP)

使用可能なオプションについては、BlendModeを参照してください。


4
正解は次の view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_ATOP);とおりです。背景または丸みを帯びたコーナーに境界がある可能性があるためです。
BerkayTurancı19年

1
素敵な1つ@BerkayTurancı私の形は角が丸くなっていた。私はgetBackground()電話を省略できました。私のimageview.srcには形状が含まれていて、私は使用しました:imageIndicator.setColorFilter(toggleColor, PorterDuff.Mode.SRC_ATOP);where toggleColorは、以前にgetColor()の結果を格納した単なるintです
Someone Somewhere

1
持つPorterDuff.ModeためにBlendModeColorFilterそれが必要とするコンパイルされませんBlendMode。したがって、API 29の場合は、このようになりますview.background.colorFilter = BlendModeColorFilter(Color.parseColor("#343434"), BlendMode.SRC_ATOP)
Onik

@Onikのグッドキャッチ。それに応じて答えを更新しました。ありがとうございました!
Georgios

14

これを試して:

 public void setGradientColors(int bottomColor, int topColor) {
 GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]  
 {bottomColor, topColor});
 gradient.setShape(GradientDrawable.RECTANGLE);
 gradient.setCornerRadius(10.f);
 this.setBackgroundDrawable(gradient);
 }

詳細については、このリンクをチェックし、これを

助けを願っています。


リンクへの賛成票。しかし、それは私の質問に対する答えではありません。
Cote Mounyo 2013

13

これが同じ問題の誰かに役立つことを願っています

GradientDrawable gd = (GradientDrawable) YourImageView.getBackground();
//To shange the solid color
gd.setColor(yourColor)

//To change the stroke color
int width_px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, youStrokeWidth, getResources().getDisplayMetrics());
gd.setStroke(width_px, yourColor);

1
当初、私は仕事にこれを得ることができませんでした、私は考え出しyourColorは:次のように提供されなければならないgd.setStroke(width_px, Color.parseColor("#FF5722"));
pwnsauce

12

リサイクルビューのアイテムなどの動的ビューに色を付ける場合は、Vikramの答えを拡張します。色を設定する前に、おそらくmutate()を呼び出します。これを行わない場合、共通のドローアブル(つまり、背景)を持つビューも、ドローアブルが変更/色付けされます。

public static void setBackgroundColorAndRetainShape(final int color, final Drawable background) {

    if (background instanceof ShapeDrawable) {
        ((ShapeDrawable) background.mutate()).getPaint().setColor(color);
    } else if (background instanceof GradientDrawable) {
        ((GradientDrawable) background.mutate()).setColor(color);
    } else if (background instanceof ColorDrawable) {
        ((ColorDrawable) background.mutate()).setColor(color);
    }else{
        Log.w(TAG,"Not a valid background type");
    }

}

3
ニーズと追加のチェックとパラメータ: if (background instanceof LayerDrawable) { background = ((LayerDrawable) background.mutate()).getDrawable(indexIfLayerDrawable); } if (background instanceof ShapeDrawable)[...]を使用する背景レイアウトを処理するため<layer-list ... <item ...
ジョニー

11

この質問はしばらく前に回答されましたが、kotlin拡張関数として書き直すことで最新化できます。

fun Drawable.overrideColor(@ColorInt colorInt: Int) {
    when (this) {
        is GradientDrawable -> setColor(colorInt)
        is ShapeDrawable -> paint.color = colorInt
        is ColorDrawable -> color = colorInt
    }
}

7

これは私のために働く解決策です...別の質問にも書いています: 形状の色を動的に変更する方法は?

//get the image button by id
ImageButton myImg = (ImageButton) findViewById(R.id.some_id);

//get drawable from image button
GradientDrawable drawable = (GradientDrawable) myImg.getDrawable();

//set color as integer
//can use Color.parseColor(color) if color is a string
drawable.setColor(color)

4

何もうまくいきませんが、色合いを設定するとShape Drawableで機能します

 Drawable background = imageView.getBackground();
 background.setTint(getRandomColor())

Android 5.0 API 21が必要


3

上記の回答に基づく私のKotlin拡張機能のバージョンとCompat

fun Drawable.overrideColor_Ext(context: Context, colorInt: Int) {
    val muted = this.mutate()
    when (muted) {
        is GradientDrawable -> muted.setColor(ContextCompat.getColor(context, colorInt))
        is ShapeDrawable -> muted.paint.setColor(ContextCompat.getColor(context, colorInt))
        is ColorDrawable -> muted.setColor(ContextCompat.getColor(context, colorInt))
        else -> Log.d("Tag", "Not a valid background type")
    }
}

1

形状を半径で埋める簡単な方法は次のとおりです。

(view.getBackground()).setColorFilter(Color.parseColor("#FFDE03"), PorterDuff.Mode.SRC_IN);

1

遅すぎるかもしれませんが、Kotlinを使用している場合は、このような方法があります

var gd = layoutMain.background as GradientDrawable

 //gd.setCornerRadius(10)
  gd.setColor(ContextCompat.getColor(ctx , R.color.lightblue))
  gd.setStroke(1, ContextCompat.getColor(ctx , R.color.colorPrimary)) // (Strokewidth,colorId)

楽しい....


0

C#Xamarinを使用している人のために、Vikramのスニペットに基づくメソッドを次に示します。

private void SetDrawableColor(Drawable drawable, Android.Graphics.Color color)
{
    switch (drawable)
    {
        case ShapeDrawable sd:
            sd.Paint.Color = color;
            break;
        case GradientDrawable gd:
            gd.SetColor(color);
            break;
        case ColorDrawable cd:
            cd.Color = color;
            break;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.