프로그래밍 방식으로 안드로이드 모양 색상 설정


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

드로어 블은 oval이미지 뷰의 배경입니다.
코트 Mounyo

요청 된이 질문이 너무 어려운 경우 여러 이미지를 캔버스에 그리고 계층화 된 최종 제품을보기의 배경으로 설정하는 방법이 있습니까?
Cote Mounyo

View클래스 를 확장하고 base위젯 ( RelativeLayout, FrameLayout)이 겹치는 레이아웃 의 뷰로 사용하여이를 수행 할 수 있습니다 . 이 확장 된 View클래스 내에서 할 수 있습니다 draw multiple images onto a canvas. 그러나 그렇게하기 전에 this-> Link (아직없는 경우)를 살펴보십시오 .
Vikram

답변:


266

참고 : background의 인스턴스가있는 시나리오를 포함하도록 답변이 업데이트되었습니다 ColorDrawable. 이것을 지적 해 준 Tyler Pfaff 에게 감사드립니다 .

드로어 블은 타원형이며 ImageView의 배경입니다.

를 가져옵니다 Drawable에서 imageView사용 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부분?
코트 무운 요

1
@TiGer @username댓글을 추가 하여 사용자에게 알림을 보내야합니다. 그런데 ShapeDrawable스트로크 부분을 설정하려면 서브 클래스 를 만들어야합니다. 더 많은 정보는 여기에서 : Link . 허용 된 답변에 문제가 있다고 언급 한 의견을보십시오.
Vikram

3
android.graphics.drawable.GradientDrawable을 android.graphics.drawable.ShapeDrawable로 캐스트 할 수 없습니다. 전송이 실패합니다
John

3
귀하의 경우 @ 존 ImageView's배경이 설정되어 GradientDrawable, getBackground()을 반환하지 않습니다 ShapeDrawable. 대신, 사용 GradientDrawable: 반환되는 것을 GradientDrawable gradientDrawable = (GradientDrawable)imageView.getBackground();... gradientDrawable.setColors(new int[] { color1, color2 });.
Vikram

2
고마워 .. 세상을 구했어
sid_09

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);같습니다. 배경 또는 둥근 택배에 테두리가있을 수 있습니다.
Berkay Turancı

1
@ BerkayTurancı 좋은 모양 내 모서리가 둥글다. 나는 getBackground()전화를 생략 할 수 있었다 . 내 imageview.src은 형태를 포함하고 내가 사용 : imageIndicator.setColorFilter(toggleColor, PorterDuff.Mode.SRC_ATOP);어디 toggleColor이전에 getColor에서 ()에서 결과를 저장하는 것이 단지 int이며
어딘가의 누군가가

1
갖는 PorterDuff.Mode위해 BlendModeColorFilter그것을 필요로 컴파일되지 않습니다 BlendMode. 따라서 API 29의 경우이어야합니다 view.background.colorFilter = BlendModeColorFilter(Color.parseColor("#343434"), BlendMode.SRC_ATOP).
오닉

잘 잡아라 @Onik. 이에 따라 답변을 업데이트했습니다. 감사합니다!
조지 오스

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

자세한 내용은이 링크를 확인

도움을 바랍니다.


링크에 투표하십시오. 그러나 그것은 내 질문에 대한 대답이 아닙니다.
코트 Mounyo

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 ....
Johny

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())

안드로이드 5.0 API 21 필요


3

Compat 위의 답변에 기반한 My Kotlin 확장 기능 버전 :

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

Radius 로 모양을 채우는 간단한 방법 은 다음 과 같습니다.

(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.