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


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.