CompoundDrawable大小

lig*_*igi 26 android

在某些情况下,Android-Lint给了我这个暗示:

此标签及其子代可以替换为一个和复合drawable

我可以在某些地方这样做,但在其他地方,缩放图像很重要,我无法做到.有没有选项可以设置复合可绘制的大小?

Ole*_*ndr 27

我终于为它发布了一个库:

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>
Run Code Online (Sandbox Code Playgroud)

和用法

    <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"
        />
Run Code Online (Sandbox Code Playgroud)

  • 真棒!我根据你的代码https://gist.github.com/hrules6872/578b52fe90c30c7445a2做了这个谢谢:) (2认同)

oni*_*nit 22

如果将代码中的图像缩放为Drawable对象,则可以使用setCompoundDrawables()TextView方法在代码中设置它们.这将需要在Drawables上调用setBounds().

据我所知,没有办法在XML中设置大小.

  • 感谢答案,即使我不喜欢这样的事实,即它不可能在XML中进行,并且必须在2个次优解决方案之间进行选择(警告不使用复合可绘制与混合布局和代码) (3认同)

pat*_*ckf 5

有一个解决方案,但它不是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>
Run Code Online (Sandbox Code Playgroud)

layout.xml

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Your text"
        android:drawableLeft="@drawable/background"
        android:drawablePadding="8dp"
        />
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是ScaleDrawables,但我想这不会在不同的像素密度上工作得很好.