Размер CompoundDrawable

Android-Lint дает мне этот намек в некоторых случаях:

Этот тег и его дети могут быть заменены на один и составной

Я мог бы сделать это в некоторых местах, но в других местах, где важно масштабирование изображения, я не могу этого сделать. Есть ли какой-либо параметр, который я могу установить размер для составного чертежа?

Ответ 1

Если вы масштабируете изображения в коде как объекты Drawable, вы можете установить их в коде с помощью метода setCompoundDrawables() TextView. Это потребует вызова setBounds() в Drawables.

Насколько я знаю, нет способа установить размер в XML.

Ответ 2

Наконец я выпустил для него библиотеку:

https://github.com/a-tolstykh/textview-rich-drawable

Используйте эту библиотеку, чтобы установить размер составного кода.

Оригинальный ответ

Вы можете добавить пользовательский атрибут к своему виду для работы с размером drawable. Конечно, это решение требует дополнительного кода, но только один раз! После того, как вы сможете решить проблему только с помощью xml (только один раз изменить элемент управления и использовать его во всех проектах).

См. мой пример:

TextViewDrawableSize.java

public class TextViewDrawableSize extends TextView {

    private int mDrawableWidth;
    private int mDrawableHeight;

    public TextViewDrawableSize(Context context) {
        super(context);
        init(context, null, 0, 0);
    }

    public TextViewDrawableSize(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0, 0);
    }

    public TextViewDrawableSize(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr, 0);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public TextViewDrawableSize(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr, defStyleRes);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TextViewDrawableSize, defStyleAttr, defStyleRes);

        try {
            mDrawableWidth = array.getDimensionPixelSize(R.styleable.TextViewDrawableSize_compoundDrawableWidth, -1);
            mDrawableHeight = array.getDimensionPixelSize(R.styleable.TextViewDrawableSize_compoundDrawableHeight, -1);
        } finally {
            array.recycle();
        }

        if (mDrawableWidth > 0 || mDrawableHeight > 0) {
            initCompoundDrawableSize();
        }
    }

    private void initCompoundDrawableSize() {
        Drawable[] drawables = getCompoundDrawables();
        for (Drawable drawable : drawables) {
            if (drawable == null) {
                continue;
            }

            Rect realBounds = drawable.getBounds();
            float scaleFactor = realBounds.height() / (float) realBounds.width();

            float drawableWidth = realBounds.width();
            float drawableHeight = realBounds.height();

            if (mDrawableWidth > 0) {
                // save scale factor of image
                if (drawableWidth > mDrawableWidth) {
                    drawableWidth = mDrawableWidth;
                    drawableHeight = drawableWidth * scaleFactor;
                }
            }
            if (mDrawableHeight > 0) {
                // save scale factor of image

                if (drawableHeight > mDrawableHeight) {
                    drawableHeight = mDrawableHeight;
                    drawableWidth = drawableHeight / scaleFactor;
                }
            }

            realBounds.right = realBounds.left + Math.round(drawableWidth);
            realBounds.bottom = realBounds.top + Math.round(drawableHeight);

            drawable.setBounds(realBounds);
        }
        setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
    }
}

attrs.xml

<resources>
    <declare-styleable name="TextViewDrawableSize">
        <attr name="compoundDrawableWidth" format="dimension"/>
        <attr name="compoundDrawableHeight" format="dimension"/>
    </declare-styleable>
</resources>

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

    <com.alt.view.TextViewDrawableSize
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/logo"
        android:drawableStart="@drawable/logo"
        android:drawablePadding="@dimen/space_micro"
        app:compoundDrawableHeight="@dimen/small_logo_height"
        app:compoundDrawableWidth="@dimen/small_logo_width"
        />

Ответ 3

Существует решение, но оно не соответствует 100%, поскольку вы не можете напрямую контролировать размер только относительного заполнения с помощью inset:

background.xml

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:insetBottom="4dp"
       android:insetTop="4dp"
       android:insetLeft="4dp"
       android:insetRight="4dp">
    <bitmap android:src="@drawable/your_icon"/>
</inset>

layout.xml

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Your text"
        android:drawableLeft="@drawable/background"
        android:drawablePadding="8dp"
        />

Еще одно решение: ScaleDrawables, но я полагаю, что это не будет работать отлично по сравнению с плотностью пикселей.

Ответ 4

Я знаю, что этот ответ немного поздний, но я бы рекомендовал использовать quickfix: "Добавить игнорировать" UseCompoundDrawables "в элемент"

Это приведет к чему-то вроде:

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:ignore="UseCompoundDrawables" >  <!-- This will remove the warning -->

    <ImageView
        android:layout_width="@dimen/icon_width"
        android:layout_height="@dimen/icon_height"
        android:contentDescription="@string/item1"
        android:src="@drawable/icon1" />

    <TextView
        android:text="@string/item1"
        android:textSize="@dimen/label_font_size" />
</LinearLayout>

Использовать с осторожностью и надеяться, что API или инструменты вскоре будут исправлены.