Встановити розмір, що малюється, програмно


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

Ви знайшли спосіб, як змінити розмір малюваного (Bitmap)?
Зелімир

2
Досить пізно, але цікаво, чому ти не дзвонив setCompoundDrawables()? Внутрішнє означає вихідний розмір зображення в інших місцях 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"

для мене проблема тут полягає в тому, що він малює білий прямокутник навколо
малюваного

8
Конструктор BitmapDrawable (Bitmap) застарілий. Використання: Drawable d = new BitmapDrawable (getResources (), Bitmap.createScaledBitmap (bitmap, 50, 50, true));
Енді,

1
Це створить пікселізацію під час масштабування малюнків. Навіть якщо це векторні малюнки.
Санкет Берде,

мабуть, хочеться використатиContextCompat.getDrawable(context, resourceid)
П'єр,

Як додаткову примітку, ви можете створювати StateListDrawableпрограмно і використовувати addStateметод із цим "перетвореним малюнком", щоб він працював для selector's itemрозміру, що використовується в setPasswordVisibilityToggleDrawable.
Фрукти

31

Вкажіть розмір з setBounds(), тобто для використання розміру 50x50

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

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


2
Після SetBounds розмір залишається незмінним. Може знадобиться якась недійсна?
Костадін

6
Насправді setBounds працює для GradientDrawables. Це просто не працює для Image Drawables.
gregm

Це спрацювало для мене, коли я клав зображення в кнопку, але не коли поміщав його в ImageView. OP використовував кнопку, але також викликав внутрішній смак setCompoundDrawables()функції.
William T. Mallard

@gregm Цікаво, що ви також можете встановити розмір для GradientDrawable за допомогою setSize ().
6rchid

12

Перш ніж застосовувати .setBounds (..), спробуйте перетворити поточний Drawable у ScaleDrawable

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

після того

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

буду працювати


2
Навіщо потрібен цей крок? Що обгортання в a ScaleDrawableдає альтернативу не обгортанню?
azizbekian

10

я не встиг розібратися, чому метод setBounds () не працює на растровому малюванні, як можна було очікувати, але у мене мало допрацьованого рішення @ androbean-studio, щоб робити те, що повинен робити setBounds ...

/**
 * 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 повинна мати 17 в build.gradle

    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 Це просто те, що він використовує для перетворення з dp на px ...
розробник android

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 (не Внутрішня версія)!


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

}

(Зверніть увагу, що я двічі використовував w, а не h, оскільки в цьому випадку я розміщував піктограму над текстом, і, таким чином, піктограма не повинна мати однакову висоту, як текстовий вигляд)

Це може бути застосовано до фонових малюнків або до будь-чого іншого, що ви хочете змінити за розміром відповідно до розміру вашого перегляду. 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

Ви можете використовувати LayerDrawable лише з одного шару та метод setLayerInset:

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 (кнопка).

Отже, 2 речі, які ви повинні зробити:

1. встановити межі:

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

2. Встановіть зображення, яке можна малювати, належним чином (без використання внутрішніх меж):

button.setCompoundDrawablesRelative(drawable, null, null, null)
  • Не потрібно використовувати растрові зображення
  • Жодних обхідних шляхів, таких як ScaleDrawable ColorDrawableабо LayerDrawable(що, безумовно, створено для інших цілей)
  • Немає потреби в користувацьких малюнках!
  • Жодних обхідних шляхів з post
  • Це рідне і просте рішення, саме те, як Android очікує від вас.

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

Використовуйте Button.setHeight()або Button.setWeight()та встановіть значення.


9
що просто встановлює висоту кнопки, а не висоту малюваного. я хочу встановити ширину / висоту малюваного (особливо якщо він більший за встановлену висоту кнопки).

21
Ви знаєте, що можете видалити відповідь, чи не так?
Iharob Al Asimi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.