Android 버튼에서 drawableLeft를 프로그래밍 방식으로 설정하는 방법은 무엇입니까?


442

동적으로 버튼을 만들고 있습니다. 먼저 XML을 사용하여 스타일을 지정했으며 아래 XML을 가져 와서 프로그래밍 방식으로 만들려고합니다.

<Button
    android:id="@+id/buttonIdDoesntMatter"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:text="buttonName"
    android:drawableLeft="@drawable/imageWillChange"
    android:onClick="listener"
    android:layout_width="fill_parent">
</Button>

이것이 내가 지금까지 가진 것입니다. 드로어 블을 제외한 모든 것을 할 수 있습니다.

linear = (LinearLayout) findViewById(R.id.LinearView);
Button button = new Button(this);
button.setText("Button");
button.setOnClickListener(listener);
button.setLayoutParams(
    new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,         
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT
    )
);      

linear.addView(button);

답변:


1054

setCompoundDrawables방법을 사용 하여이 작업을 수행 할 수 있습니다 . 여기 의 예를 참조 하십시오 . 나는 이것을 사용하지 않고 이것을 사용했고 setBounds효과가있었습니다. 어느 쪽이든 시도 할 수 있습니다.

업데이트 : 링크가 다운되는 경우 코드 복사

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
img.setBounds(0, 0, 60, 60);
txtVw.setCompoundDrawables(img, null, null, null);

또는

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
txtVw.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);

또는

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

@Varun, @Tigger : 이것에 문제가 있습니다 : 내 파일 관리자는 텍스트보기와 폴더 아이콘이있는 목록보기에서 폴더를 보여줍니다 drawableLeft. 읽기 권한이없는 폴더를 클릭 할 때 "금지 된 아이콘"을 설정하기 위해 여기에서 제안을 시도했지만 작동합니다. 그러나 폴더를 변경하고 어댑터를 다시로드하면 금지 된 아이콘이 유지됩니다 (즉, drawableLeft다시 그려지지 않음). 당신이 적용하는 방법을 알아 notifyDataSetChanged에 대해서도 drawableLeft루프를하지 않고,? 감사!
Luis A. Florit

@ LuisA.Florit Listview데이터가 변경 될 때 항목 다시 그리기 와 관련된 질문이있는 것 같습니다.이 질문 또는 답변과 실제로 관련이 없습니다. 의견 대신 질문을 올리는 것이 좋습니다.
Tigger

@ 티거 : 글쎄, 나는 또한 당신의 트릭을 사용하여 아이콘을 되돌리고 금지 된 디렉토리를 반복합니다. 어쩌면 이것은 모든 ListView 항목을 다시 그리는 것보다 낫습니다 ... 어쨌든 감사합니다!
Luis A. Florit

3
내 앱에 이상한 것이 있습니다. 는 setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )내가 layout.xml에 drawableRight를 정의하면,하지 작업을 수행합니다. 안에 원래 아이콘을 설정 onCreate()하면 변경 사항이 적용됩니다. API 19와 관련이있을 수 있습니까?
인젝터

링크 예가 열리지 않습니다. 대체 링크가 있습니까?
Yogesh Umesh Vaity

100

간단히 시도해 볼 수도 있습니다

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4
이 메소드의 정의는 {public void setCompoundDrawablesWithIntrinsicBounds (int left, int top, int right, int bottom)}이기 때문에 R.drawable.smiley는 첫 번째 0 (첫 번째 매개 변수) 대신 마지막
이어야합니다.

이 주위에 패딩을 추가하려면 어떻게해야합니까? 이 방법으로 드로어 블과 텍스트 사이에 패딩이 많지 않습니다.
AdamMc331

16

Kotlin Version

아래 스 니펫을 사용하여 버튼에 드로어 블 왼쪽을 추가하십시오.

val drawable = ContextCompat.getDrawable(context, R.drawable.ic_favorite_white_16dp)
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

.

Important Point in Using Android Vector Drawable

Android 벡터 드로어 블을 사용 중이고 21 미만의 API에 대한 이전 버전과의 호환성을 원할 경우 다음 코드를 추가하십시오.

응용 프로그램 수준에서 build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

응용 프로그램 클래스에서 :

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

나를 위해 작동하는 간단한 방법 : button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf

2
귀하는 옳지 만 Context#.getDrawable(resId)더 이상 사용되지 않으므로 사용하면 일부 문제가 발생할 수 있습니다.
aminography

응용 프로그램 클래스가 없기 때문에 추가하지 않고 작동합니다.
마크 델파이

15

나를 위해, 그것은 효과가 있었다 :

button.setCompoundDrawablesWithIntrinsicBounds(com.example.project1.R.drawable.ic_launcher, 0, 0, 0);

13
myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4

나는 이걸했다:

 // Left, top, right, bottom drawables.
            Drawable[] drawables = button.getCompoundDrawables();
            // get left drawable.
            Drawable leftCompoundDrawable = drawables[0];
            // get new drawable.
            Drawable img = getContext().getResources().getDrawable(R.drawable.ic_launcher);
            // set image size (don't change the size values)
            img.setBounds(leftCompoundDrawable.getBounds());
            // set new drawable
            button.setCompoundDrawables(img, null, null, null);

4

당신이 사용하는 경우 drawableStart , drawableEnd , drawableTop 또는 drawableBottom을 ; " setCompoundDrawablesRelativeWithIntrinsicBounds " 를 사용해야합니다.

edittext.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.anim_search_to_close, 0)

3

나를 위해 일했다. 오른쪽에 드로어 블을 설정하려면

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)

2

@ Jérémy Reynaud가 지적 했듯이이 답변에 설명 된 것처럼 다른 드로어 블 (위, 오른쪽 및 아래쪽)의 값을 변경하지 않고 왼쪽 드로어 블을 설정하는 가장 안전한 방법은 setCompoundDrawablesWithIntrinsicBounds 버튼으로 이전 값을 사용하는 것입니다 .

Drawable leftDrawable = getContext().getResources()
                          .getDrawable(R.drawable.yourdrawable);

// Or use ContextCompat
// Drawable leftDrawable = ContextCompat.getDrawable(getContext(),
//                                        R.drawable.yourdrawable);

Drawable[] drawables = button.getCompoundDrawables();
button.setCompoundDrawablesWithIntrinsicBounds(leftDrawable,drawables[1],
                                               drawables[2], drawables[3]);

따라서 모든 이전 드로어 블이 유지됩니다.


2

다음은 텍스트 편집에서 왼쪽 아이콘의 색상을 변경하고 왼쪽에서 설정하는 방법입니다.

 Drawable img = getResources().getDrawable( R.drawable.user );
img.setBounds( 0, 0, 60, 60 );
mNameEditText.setCompoundDrawables(img,null, null, null);

int color = ContextCompat.getColor(this, R.color.blackColor);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    DrawableCompat.setTint(img, color);

} else {
    img.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}

1

도움이 될 수 있습니다.

TextView location;
location=(TextView)view.findViewById(R.id.complain_location);
//in parameter (left,top,right,bottom) any where you wnat to put
location.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.arrow,0);

1

Kotlin 확장 기능 추가

이 작업을 자주 수행하려는 경우 확장을 추가하면 코드를 더 읽기 쉽게 만들 수 있습니다. 버튼은 TextView를 확장합니다. 더 좁히려면 버튼을 사용하십시오.

fun TextView.leftDrawable(@DrawableRes id: Int = 0) {
    this.setCompoundDrawablesWithIntrinsicBounds(id, 0, 0, 0)
}

내선 번호를 사용하려면 전화

view.leftDrawable(R.drawable.my_drawable)

삭제해야 할 때마다 매개 변수를 전달하거나 removeDrawables


0

이 시도:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
     fillButton[i].setBackground(getBaseContext().getResources().getDrawable(R.drawable.drawable_name));
}
else {
    fillButton[i].setBackgroundColor(Color.argb(255,193,234,203));
}

-8

이 시도:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);

myEdtiText.setCompoundDrawablesWithIntrinsicBounds (R.drawable.smiley, 0, 0, 0); 작품
Debasish Ghosh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.