Programlı olarak çekilebilir boyutu ayarlayın


92

Görüntüler (simgeler) aşağı yukarı aynı boyutta geliyor, ancak düğmelerin aynı yükseklikte kalması için onları yeniden boyutlandırmam gerekiyor.

Bunu nasıl yaparım?

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

Drawable'ı (Bitmap) yeniden boyutlandırma yolunu buldunuz mu?
Zelimir

2
Çok geç ama neden aramadığını merak ediyor musun setCompoundDrawables()? Intrinsic, Android içindeki diğer yerlerdeki orijinal görüntü boyutunu ifade eder, ör Drawable.getIntrinsicHeight().
William T. Mallard

Yanıtlar:


160

setBounds()Yöntem kabın her tür işi yapmaz (benim bazıları için çalışma yaptı ImageViewancak 's).

Çekilebilir dosyanın kendisini ölçeklendirmek için aşağıdaki yöntemi deneyin:

// 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"

benim için buradaki sorun, çizilebilir görüntünün etrafına beyaz bir dikdörtgen
çizmesidir

8
BitmapDrawable (Bitmap) yapıcısı kullanımdan kaldırıldı. Kullanın: Drawable d = new BitmapDrawable (getResources (), Bitmap.createScaledBitmap (bitmap, 50, 50, true));
Andy

1
Bu, çekilebilir öğeleri ölçeklendirirken pikselleştirme yaratacaktır. Vektör çizimleri olsalar bile.
Sanket Berde

muhtemelen kullanmak isterContextCompat.getDrawable(context, resourceid)
Pierre

Bir yan not olarak, StateListDrawableprogramlı olarak oluşturabilir ve addStatebu "dönüştürülmüş çekilebilir" yöntemiyle, selector's itemkullanılan boyutta çalışmasını sağlamak için yöntemi kullanabilirsiniz setPasswordVisibilityToggleDrawable.
Fruit

31

Boyutu ile belirtin setBounds(), yani 50x50 boyutunda kullanım için

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

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


2
SetBounds'dan sonra boyutu aynı kalır. Bazı geçersiz kılma gerekli olabilir mi?
Kostadin

6
Aslında setBounds, GradientDrawables için çalışır. Sadece Image Drawables için çalışmıyor.
gregm

Görüntüyü bir düğmeye koyarken işe yaradı, ancak bir ImageView'a koyduğumda işe yaramadı. OP bir düğme kullanıyordu, ancak aynı zamanda işlevin kendine özgü tadını da çağırıyordu setCompoundDrawables().
William T. Mallard

@gregm İlginç bir şekilde, setSize () kullanarak GradientDrawable'ın boyutunu da ayarlayabilirsiniz.
6rchid

12

.SetBounds'u (..) uygulamadan önce, mevcut Drawable'ı ScaleDrawable'a dönüştürmeyi deneyin

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

Daha sonra

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

çalışacak


2
Bu adım neden gerekli? Hangi sarma, sarmalamamaya ScaleDrawablealternatif verir?
azizbekian

10

setBounds () yönteminin beklendiği gibi bitmap çizilebilir üzerinde neden çalışmadığını kazmaya vaktim olmadı, ancak setBounds'un yapması gereken şeyi yapmak için @ androbean-studio çözümüm çok az ayarlandı ...

/**
 * 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;
    }
}

kullanım:

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

Sonuçlar

önce: görüntü açıklamasını buraya girin sonra:görüntü açıklamasını buraya girin


sola dolgu nasıl eklenir?
reegan29

8

Kullanmak

textView.setCompoundDrawablesWithIntrinsicBounds()

MinSdkVersion'ınız build.gradle'da 17 olmalıdır

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

Çekilebilir boyutu değiştirmek için:

    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

İstenilen efekti elde etmek için gönderme yöntemini kullanın:

{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

Muhtemelen biraz geç. Ama işte nihayet her durumda benim için işe yarayan çözüm.

Buradaki fikir, sabit iç boyuta sahip özel bir çizim oluşturmak ve çizim işini orijinal çekilebilir duruma geçirmektir.

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 nedir?
batsheva

@batsheva Bu sadece dp'den px'e dönüşüm için kullandığı bir şey ...
android geliştiricisi

2

jkhouw1 yanıtı doğrudur, ancak bazı ayrıntılardan yoksundur, aşağıya bakın:

En azından API> 21 için çok daha kolaydır. Kaynaklardan VectorDrawable'a sahip olduğumuzu varsayalım (onu almak için örnek kod):

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

Bu VectorDrawable için sadece istenen boyutu ayarlayın:

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

Ve düğme içinde çekilebilir göster:

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

Bu kadar. Ancak setCompoundDrawables'ı (Intrinsic sürümü değil) kullanmayı unutmayın!


1

Bunu LayerDrawable kullanarak çalıştırdım:

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

Misal:

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)

0

Görünüm türünün bir alt sınıfını oluşturabilir ve onSizeChanged yöntemini geçersiz kılabilirsiniz.

Metin görünümlerimde, xml'deki bitmap çekilebilirlerini vb. Tanımlama ile uğraşmamı gerektirmeyen bileşik çekmeceleri ölçeklendirmek istedim ve bunu şu şekilde yaptım:

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

}

(Bu durumda, simgeyi metnin üzerine koyduğumdan, h yerine iki kez w kullandığımı ve bu nedenle simgenin metin görünümüyle aynı yükseklikte olmaması gerektiğini unutmayın)

Bu, arka plan çekmecelerine veya görünüm boyutunuza göre yeniden boyutlandırmak istediğiniz herhangi bir şeye uygulanabilir. onSizeChanged (), Görünüm ilk kez yapıldığında çağrılır, bu nedenle boyutu başlatmak için herhangi bir özel duruma ihtiyacınız yoktur.


0

Deneyebilirsin button.requestLayout(). Arka plan boyutu değiştirildiğinde, yeniden ölçülmesi ve düzenlenmesi gerekir, ancak bunu yapmaz


-1

LayerDrawable'ı yalnızca bir katmandan ve setLayerInset yönteminden kullanabilirsiniz:

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

Sorunun sorulmasının üzerinden epey bir zaman geçti,
ancak bu basit şeyin nasıl yapılacağı hala belirsiz.

Bu durumda bir Drawable'ı bir TextView (Düğme) üzerinde bileşik bir çizim olarak kullandığınızda oldukça basittir.

Yani yapmanız gereken 2 şey:

1. Sınırları belirleyin:

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

2. Çekilebilirliği uygun şekilde ayarlayın (iç sınırlar kullanmadan):

button.setCompoundDrawablesRelative(drawable, null, null, null)
  • Bitmap kullanmaya gerek yok
  • ScaleDrawable ColorDrawableVeya gibi geçici çözümler yokLayerDrawable (kesinlikle başka amaçlar için oluşturulmuş olanlar)
  • Özel çekmecelere gerek yok!
  • İle geçici çözüm yok post
  • Tam da Android'in sizden beklediği gibi yerel ve basit bir çözüm.

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

Button.setHeight()Veya kullanın Button.setWeight()ve bir değer ayarlayın.


9
bu sadece düğme yüksekliğini ayarlar, çekmecenin yüksekliğini değil. Çekilebilir öğenin genişliğini / yüksekliğini ayarlamak istiyorum (özellikle ayarlanan düğme yüksekliğinden büyükse).

23
Cevabı silebileceğini biliyorsun, değil mi?
Iharob Al Asimi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.