Как я могу уменьшить рисунок на кнопке? - PullRequest
81 голосов
/ 24 сентября 2011

как я могу сделать рисование на кнопке меньше?Значок слишком большой, на самом деле выше, чем кнопка.Вот код, который я использую:

    <Button
    android:background="@drawable/red_button"
    android:drawableLeft="@drawable/s_vit"
    android:id="@+id/ButtonTest"
    android:gravity="left|center_vertical" 
    android:text="S-SERIES CALCULATOR"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginLeft="25dp"
    android:layout_marginRight="25dp"
    android:drawablePadding="10dp">
    </Button>

Чем больше он выглядит, тем ниже он выглядит прямо сейчас.это, но изображение не отображается.: - (

    Resources res = getResources();
    ScaleDrawable sd = new ScaleDrawable(res.getDrawable(R.drawable.s_vit), 0, 10f, 10f);
    Button btn = (Button) findViewById(R.id.ButtonTest);
    btn.setCompoundDrawables(sd.getDrawable(), null, null, null);

Ответы [ 15 ]

85 голосов
/ 28 августа 2015

Я нашел очень простое и эффективное решение XML, которое не требует ImageButton

Создайте нарисованный файл для вашего изображения, как показано ниже, и используйте его для android:drawableLeft

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
    android:id="@+id/half_overlay"
    android:drawable="@drawable/myDrawable"
    android:width="40dp"
    android:height="40dp"
    />

</layer-list>

Вы можете установить размер изображения с помощью свойств android:width и android:height.

Таким образом, вы можете, по крайней мере, получить одинаковый размер для разных экранов.

Недостатком является то, что ононе совсем как fitXY, который масштабировал бы ширину изображения, чтобы соответствовать X и соответственно масштабировал высоту изображения.

68 голосов
/ 24 сентября 2011

Вы должны использовать ImageButton и указать изображение в android:src, а для android:scaletype установить fitXY


Настройка масштабируемой отрисовки в коде

Drawable drawable = getResources().getDrawable(R.drawable.s_vit);
drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*0.5), 
                         (int)(drawable.getIntrinsicHeight()*0.5));
ScaleDrawable sd = new ScaleDrawable(drawable, 0, scaleWidth, scaleHeight);
Button btn = findViewbyId(R.id.yourbtnID);
btn.setCompoundDrawables(sd.getDrawable(), null, null, null); //set drawableLeft for example
10 голосов
/ 24 декабря 2011

Кнопки не меняют размеры своих внутренних изображений.

Мое решение не требует манипулирования кодом.

Используется макет с TextView и ImageView.

Фон макета должен быть нарисован красным цветом.

Возможно, вам потребуется определить атрибут android: scaleType xml.

Пример:

<LinearLayout
    android:id="@+id/list_item"
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:padding="2dp" >

    <ImageView
        android:layout_width="50dp"
        android:layout_height="fill_parent"
        android:src="@drawable/camera" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:lines="1"
        android:gravity="center_vertical"
        android:text="Hello - primary" />

</LinearLayout>

КСТАТИ:

  1. Подсчет значков с разным разрешением может привести к непредсказуемому пользовательскому интерфейсу (значок слишком большой или слишком маленький)
  2. Текст в текстовом представлении (включая кнопки) не заполняет компонент. Это проблема Android, и я не знаю, как ее решить.
  3. Вы можете использовать его как включающий.

Удачи

6 голосов
/ 21 января 2016

Мой DiplayScaleHelper, который отлично работает:

import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ScaleDrawable;
import android.widget.Button;

public class DisplayHelper {

  public static void scaleButtonDrawables(Button btn, double fitFactor) {
        Drawable[] drawables = btn.getCompoundDrawables();

        for (int i = 0; i < drawables.length; i++) {
            if (drawables[i] != null) {
                if (drawables[i] instanceof ScaleDrawable) {
                    drawables[i].setLevel(1);
                }
                drawables[i].setBounds(0, 0, (int) (drawables[i].getIntrinsicWidth() * fitFactor),
                    (int) (drawables[i].getIntrinsicHeight() * fitFactor));
                ScaleDrawable sd = new ScaleDrawable(drawables[i], 0, drawables[i].getIntrinsicWidth(), drawables[i].getIntrinsicHeight());
                if(i == 0) {
                    btn.setCompoundDrawables(sd.getDrawable(), drawables[1], drawables[2], drawables[3]);
                } else if(i == 1) {
                    btn.setCompoundDrawables(drawables[0], sd.getDrawable(), drawables[2], drawables[3]);
                } else if(i == 2) {
                    btn.setCompoundDrawables(drawables[0], drawables[1], sd.getDrawable(), drawables[3]);
                } else {
                    btn.setCompoundDrawables(drawables[0], drawables[1], drawables[2], sd.getDrawable());
                }
            }
        }
    }
}
6 голосов
/ 04 декабря 2012

Используйте ScaleDrawable в качестве Предложено Abhinav .

Проблема в том, что рисование тогда не отображается - это какая-то ошибка в ScaleDrawables.вам нужно изменить «уровень» программно.Это должно работать для каждой кнопки:

// Fix level of existing drawables
Drawable[] drawables = myButton.getCompoundDrawables();
for (Drawable d : drawables) if (d != null && d instanceof ScaleDrawable) d.setLevel(1);
myButton.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
4 голосов
/ 09 сентября 2015

Вы можете вызвать setBounds на «составных» чертежах, чтобы изменить размер изображения.

Попробуйте этот код для автоматического изменения размера вашей кнопки:

DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0);

, определенной этой функцией:

public final class DroidUtils {

    /** scale the Drawables of a button to "fit"
     *  For left and right drawables: height is scaled 
     *  eg. with fitFactor 1 the image has max. the height of the button.
     *  For top and bottom drawables: width is scaled: 
     *  With fitFactor 0.9 the image has max. 90% of the width of the button 
     *  */
    public static void scaleButtonDrawables(Button btn, double fitFactor) {
        Drawable[] drawables = btn.getCompoundDrawables();

        for (int i = 0; i < drawables.length; i++) {
            if (drawables[i] != null) {
                int imgWidth = drawables[i].getIntrinsicWidth();
                int imgHeight = drawables[i].getIntrinsicHeight();
                if ((imgHeight > 0) && (imgWidth > 0)) {    //might be -1
                    float scale;
                    if ((i == 0) || (i == 2)) { //left or right -> scale height
                        scale = (float) (btn.getHeight() * fitFactor) / imgHeight;
                    } else { //top or bottom -> scale width
                        scale = (float) (btn.getWidth() * fitFactor) / imgWidth;                    
                    }
                    if (scale < 1.0) {
                        Rect rect = drawables[i].getBounds();
                        int newWidth = (int)(imgWidth * scale);
                        int newHeight = (int)(imgHeight * scale);
                        rect.left = rect.left + (int)(0.5 * (imgWidth - newWidth)); 
                        rect.top = rect.top + (int)(0.5 * (imgHeight - newHeight));
                        rect.right = rect.left + newWidth;
                        rect.bottom = rect.top + newHeight;
                        drawables[i].setBounds(rect);
                    }
                }
            }
        }
    }
}

Имейте в виду, что это не может быть вызвано вonCreate() действия, потому что высота и ширина кнопки там (пока) недоступны.Вызовите это на onWindowFocusChanged() или используйте это решение для вызова функции.

Отредактировано:

Первое воплощение этой функции не работало правильно.Он использовал код userSeven7s для масштабирования изображения, но возвращение ScaleDrawable.getDrawable() , похоже, не работает (и не возвращает ScaleDrawable) для меня.

В измененном коде используется setBoundsпредоставить границы для изображения.Android вписывает изображение в эти границы.

1 голос
/ 03 апреля 2019

Я делаю это, как показано ниже. Это создает изображение размером 100x100 в кнопке независимо от входного изображения.

drawable.bounds = Rect(0,0,100,100)
button.setCompoundDrawables(drawable, null, null, null)

Также не использовать ScaleDrawable. Отсутствие button.setCompoundDrawablesRelativeWithIntrinsicBounds() решило мою проблему, так как кажется, что вместо установленных вами границ используются внутренние границы (размер исходного изображения).

1 голос
/ 24 сентября 2011

Если вы хотите использовать 1 изображение и отображать его в другом размере, вы можете использовать масштабируемое рисование (http://developer.android.com/guide/topics/resources/drawable-resource.html#Scale).

0 голосов
/ 27 мая 2018

Я создал пользовательский класс кнопок для этого.

CustomButton.java

public class CustomButton extends android.support.v7.widget.AppCompatButton {

    private Drawable mDrawable;

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomButton,
                0, 0);

        try {
            float mWidth = a.getDimension(R.styleable.CustomButton_drawable_width, 0);
            float mHeight = a.getDimension(R.styleable.CustomButton_drawable_width, 0);

            Drawable[] drawables = this.getCompoundDrawables();
            Drawable[] resizedDrawable = new Drawable[4];

            for (int i = 0; i < drawables.length; i++) {
                if (drawables[i] != null) {
                    mDrawable = drawables[i];
                }
                resizedDrawable[i] = getResizedDrawable(drawables[i], mWidth, mHeight);
            }

            this.setCompoundDrawables(resizedDrawable[0], resizedDrawable[1], resizedDrawable[2], resizedDrawable[3]);
        } finally {
            a.recycle();
        }
    }

    public Drawable getmDrawable() {
        return mDrawable;
    }

    private Drawable getResizedDrawable(Drawable drawable, float mWidth, float mHeight) {
        if (drawable == null) {
            return null;
        }

        try {
            Bitmap bitmap;

            bitmap = Bitmap.createBitmap((int)mWidth, (int)mHeight, Bitmap.Config.ARGB_8888);

            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return drawable;
        } catch (OutOfMemoryError e) {
            // Handle the error
            return null;
        }
    }
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomButton">
        <attr name="drawable_width" format="dimension" />
        <attr name="drawable_height" format="dimension" />
    </declare-styleable>
</resources>

Использование в xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.MainActivity">

     <com.example.CustomButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/ic_hero"
            android:text="Avenger"
            custom:drawable_height="10dp"
            custom:drawable_width="10dp" />

</RelativeLayout>
0 голосов
/ 08 июня 2017

Это потому, что вы не setLevel.после того, как вы setLevel(1), он будет отображаться как вы хотите

...