프로그래밍 방식으로 드로어 블 크기 설정


91

이미지 (아이콘)의 크기는 거의 같지만 버튼의 높이를 동일하게 유지하려면 크기를 조정해야합니다.

어떻게해야합니까?

Button button = new Button(this);
button.setText(apiEventObject.getTitle());
button.setOnClickListener(listener);

/*
 * set clickable id of button to actual event id
 */
int id = Integer.parseInt(apiEventObject.getId());
button.setId(id);

button.setLayoutParams(new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT));

Drawable drawable = LoadImageFromWebOperations(apiSizeObject.getSmall());
//?resize drawable here? drawable.setBounds(50, 50, 50, 50);
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);

드로어 블 (비트 맵)의 크기를 조정하는 방법을 찾았습니까?
— Zelimir

2
늦었지만 왜 전화하지 않았는지 궁금 setCompoundDrawables()하십니까? Intrinsic은 Android 내의 다른 위치에있는 원본 이미지 크기 (예 : Drawable.getIntrinsicHeight().
— William T. Mallard

답변:


159

이 setBounds()방법은 모든 유형의 컨테이너에서 작동하지 않습니다 ( ImageView그러나 일부 컨테이너에서는 작동했습니다 ).

드로어 블 자체의 크기를 조정하려면 아래 방법을 시도하십시오.

// Read your drawable from somewhere
Drawable dr = getResources().getDrawable(R.drawable.somedrawable);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
// Scale it to 50 x 50
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, 50, 50, true));
// Set your new, scaled drawable "d"

여기에서 문제는 드로어 블 이미지 주위에 흰색 직사각형을 그리는 것입니다
— noloman

8
BitmapDrawable (Bitmap) 생성자는 더 이상 사용되지 않습니다. 사용 : Drawable d = new BitmapDrawable (getResources (), Bitmap.createScaledBitmap (bitmap, 50, 50, true));
— Andy

1
이것은 드로어 블을 확대 할 때 픽셀 화를 생성합니다. 벡터 드로어 블이더라도.
— Sanket Berde 2017 년

아마도 사용하고 싶을 것입니다ContextCompat.getDrawable(context, resourceid)
— Pierre

참고로, StateListDrawable프로그래밍 addState방식으로 생성하고 "변환 된 드로어 블"과 함께 메서드를 selector's item사용하여 setPasswordVisibilityToggleDrawable.
— Fruit

31

로 크기 지정 setBounds(), 즉 50x50 크기 사용

drawable.setBounds(0, 0, 50, 50);

public void setBounds (int left, int top, int right, int bottom)


2
SetBounds 후 크기는 동일하게 유지됩니다. 무효화가 필요할 수 있습니까?
— Kostadin 2012

6
실제로 setBounds는 GradientDrawables에서 작동합니다. Image Drawables에서는 작동하지 않습니다.
— gregm

이미지를 버튼에 넣을 때는 효과가 있었지만 ImageView에 넣을 때는 효과가 없었습니다. OP는 버튼을 사용하고 있었지만 함수의 본질적인 풍미도 호출했습니다 setCompoundDrawables().
— William T. Mallard

@gregm 흥미롭게도 setSize ()를 사용하여 GradientDrawable의 크기를 설정할 수도 있습니다.
— 6rchid

12

.setBounds (..)를 적용하기 전에 현재 Drawable을 ScaleDrawable로 변환 해보십시오.

drawable = new ScaleDrawable(drawable, 0, width, height).getDrawable();

그 후

drawable.setBounds(0, 0, width, height);

작동 할 것이다


2
이 단계가 필요한 이유는 무엇입니까? 의 어떤 포장 ScaleDrawable이 비 포장에 대한 대안을 제공합니까?
— azizbekian

10

setBounds () 메서드가 예상대로 비트 맵 드로어 블에서 작동하지 않는 이유를 파헤칠 시간이 없었지만 setBounds가해야 할 일을하기 위해 @ androbean-studio 솔루션을 약간 조정했습니다 ...

/**
 * Created by ceph3us on 23.05.17.
 * file belong to pl.ceph3us.base.android.drawables
 * this class wraps drawable and forwards draw canvas
 * on it wrapped instance by using its defined bounds
 */
public class WrappedDrawable extends Drawable {

    private final Drawable _drawable;
    protected Drawable getDrawable() {
        return _drawable;
    }

    public WrappedDrawable(Drawable drawable) {
        super();
        _drawable = drawable;
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        //update bounds to get correctly
        super.setBounds(left, top, right, bottom);
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setBounds(left, top, right, bottom);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setAlpha(alpha);
        }
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.setColorFilter(colorFilter);
        }
    }

    @Override
    public int getOpacity() {
        Drawable drawable = getDrawable();
        return drawable != null
                ? drawable.getOpacity()
                : PixelFormat.UNKNOWN;
    }

    @Override
    public void draw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            drawable.draw(canvas);
        }
    }

    @Override
    public int getIntrinsicWidth() {
        Drawable drawable = getDrawable();
        return drawable != null
                ? drawable.getBounds().width()
                : 0;
    }

    @Override
    public int getIntrinsicHeight() {
        Drawable drawable = getDrawable();
        return drawable != null ?
                drawable.getBounds().height()
                : 0;
    }
}

용법:

// get huge drawable 
final Drawable drawable = resources.getDrawable(R.drawable.g_logo);
// create our wrapper           
WrappedDrawable wrappedDrawable = new WrappedDrawable(drawable);
// set bounds on wrapper 
wrappedDrawable.setBounds(0,0,32,32); 
// use wrapped drawable 
Button.setCompoundDrawablesWithIntrinsicBounds(wrappedDrawable ,null, null, null);

결과

이전 : 여기에 이미지 설명 입력 이후 :여기에 이미지 설명 입력


패딩을 왼쪽에 추가하는 방법?
— reegan29

8

쓰다

textView.setCompoundDrawablesWithIntrinsicBounds()

minSdkVersion은 build.gradle에서 17이어야합니다.

    defaultConfig {
    applicationId "com.example..."
    minSdkVersion 17
    targetSdkVersion 25
    versionCode 1
    versionName "1.0"
}

드로어 블 크기를 변경하려면 :

    TextView v = (TextView)findViewById(email);
    Drawable dr = getResources().getDrawable(R.drawable.signup_mail);
    Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
    Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, 80, 80, true));

    //setCompoundDrawablesWithIntrinsicBounds (image to left, top, right, bottom)
    v.setCompoundDrawablesWithIntrinsicBounds(d,null,null,null);

3

포스트 방법을 사용하여 원하는 효과를 얻으십시오.

{your view}.post(new Runnable()
    {
        @Override
        public void run()
        {
            Drawable image = context.getResources().getDrawable({drawable image resource id});
            image.setBounds(0, 0, {width amount in pixels}, {height amount in pixels});
            {your view}.setCompoundDrawables(image, null, null, null);
        }
    });

3

아마 조금 늦었을 것입니다. 그러나 여기에 모든 상황에서 마침내 나를 위해 일한 솔루션이 있습니다.

아이디어는 고정 된 크기의 사용자 정의 드로어 블을 만들고 드로잉 작업을 원본 드로어 블에 전달하는 것입니다.

Drawable icon = new ColorDrawable(){
        Drawable iconOrig = resolveInfo.loadIcon(packageManager);

        @Override
        public void setBounds(int left, int top, int right, int bottom){
            super.setBounds(left, top, right, bottom);//This is needed so that getBounds on this class would work correctly.
            iconOrig.setBounds(left, top, right, bottom);
        }

        @Override
        public void draw(Canvas canvas){
            iconOrig.draw(canvas);
        }

        @Override
        public int getIntrinsicWidth(){
            return  mPlatform.dp2px(30);
        }

        @Override
        public int getIntrinsicHeight(){
            return  mPlatform.dp2px(30);
        }
    };

mPlatform이란 무엇입니까?
— batsheva

@batsheva 그것은 그가 dp에서 px로 변환하는 데 사용하는 것입니다 ...
— 안드로이드 개발자

2

jkhouw1 답변은 정답이지만 세부 정보가 부족합니다. 아래를 참조하십시오.

API> 21 이상인 경우 훨씬 더 쉽습니다. 리소스에서 VectorDrawable이 있다고 가정합니다 (검색하는 예제 코드).

val iconResource = context.resources.getIdentifier(name, "drawable", context.packageName)
val drawable = context.resources.getDrawable(iconResource, null)

해당 VectorDrawable에 대해 원하는 크기를 설정하십시오.

drawable.setBounds(0, 0, size, size)

그리고 버튼에 드로어 블 표시 :

button.setCompoundDrawables(null, drawable, null, null)

그게 다야. 그러나 setCompoundDrawables (Intrinsic 버전이 아님)를 사용하십시오!


0

뷰 유형의 하위 클래스를 만들고 onSizeChanged 메서드를 재정의 할 수 있습니다.

xml 등에서 비트 맵 드로어 블을 정의 할 필요가없는 내 텍스트 뷰에서 복합 드로어 블을 확장하고 싶었습니다.

public class StatIcon extends TextView {

    private Bitmap mIcon;

    public void setIcon(int drawableId) {
    mIcon = BitmapFactory.decodeResource(RIApplication.appResources,
            drawableId);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if ((w > 0) && (mIcon != null))
            this.setCompoundDrawablesWithIntrinsicBounds(
                null,
                new BitmapDrawable(Bitmap.createScaledBitmap(mIcon, w, w,
                        true)), null, null);

        super.onSizeChanged(w, h, oldw, oldh);
    }

}

(이 경우에는 아이콘을 텍스트 위에 놓았으므로 아이콘의 높이가 텍스트보기와 같지 않아야하므로 h가 아니라 w를 두 번 사용했습니다.)

이것은 배경 드로어 블 또는보기 크기에 따라 크기를 조정하려는 다른 모든 항목에 적용 할 수 있습니다. onSizeChanged ()는 뷰가 처음 만들어 질 때 호출되므로 크기를 초기화하는 데 특별한 경우가 필요하지 않습니다.


0

시도해 볼 수 있습니다 button.requestLayout(). 배경 크기가 변경되면 재 측정 및 레이아웃이 필요하지만 작동하지 않습니다.


0

LayerDrawable을 사용하여 작동했습니다.

fun getResizedDrawable(drawable: Drawable, scale: Float) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, (drawable.intrinsicWidth * scale).toInt(), (drawable.intrinsicHeight * scale).toInt()) }

fun getResizedDrawable(drawable: Drawable, scalex: Float, scaleY: Float) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, (drawable.intrinsicWidth * scalex).toInt(), (drawable.intrinsicHeight * scaleY).toInt()) }

fun getResizedDrawableUsingSpecificSize(drawable: Drawable, newWidth: Int, newHeight: Int) =
    LayerDrawable(arrayOf(drawable)).also { it.setLayerSize(0, newWidth, newHeight) }

예:

val drawable = AppCompatResources.getDrawable(this, android.R.drawable.sym_def_app_icon)!!
val resizedDrawable = getResizedDrawable(drawable, 3f)
textView.setCompoundDrawablesWithIntrinsicBounds(resizedDrawable, null, null, null)
imageView.setImageDrawable(resizedDrawable)

-1

하나의 레이어와 setLayerInset 메서드에서만 LayerDrawable을 사용할 수 있습니다.

Drawable[] layers = new Drawable[1];
layers[0] = application.getResources().getDrawable(R.drawable.you_drawable);

LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.setLayerInset(0, 10, 10, 10, 10);

-1

질문
을 한 지 오래되었지만이 간단한 일을 수행하는 방법이 아직 명확하지 않습니다.

이 경우 Drawable을 TextView (Button)의 복합 드로어 블로 사용하는 것은 매우 간단합니다.

따라서해야 할 두 가지 :

1. 경계 설정 :

drawable.setBounds(left, top, right, bottom)

2. 드로어 블을 적절하게 설정합니다 (내재 경계를 사용하지 않음).

button.setCompoundDrawablesRelative(drawable, null, null, null)
  • 비트 맵을 사용할 필요가 없습니다.
  • ScaleDrawable ColorDrawable또는 LayerDrawable(다른 목적을 위해 생성 된 것) 과 같은 해결 방법 없음
  • 커스텀 드로어 블이 필요 없습니다!
  • 해결 방법이 없습니다. post
  • Android가 기대하는대로 기본적이고 간단한 솔루션입니다.

-43
Button button = new Button(this);
Button = (Button) findViewById(R.id.button01);

Button.setHeight()또는 사용 Button.setWeight()하고 값을 설정합니다.


9
드로어 블의 높이가 아닌 버튼 높이 만 설정합니다. 드로어 블의 너비 / 높이를 설정하고 싶습니다 (특히 설정된 버튼 높이보다 큰 경우).

22
답을 삭제할 수 있다는 것을 알고 있지 않습니까?
— Iharob Al Asimi 2015-08-16
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.