drawableStart в кнопке не масштабируется правильно - PullRequest
2 голосов
/ 30 июня 2019

У меня есть drawableStart значок, который можно нарисовать в моем Button ниже, но он не масштабируется правильно.Что я могу сделать, чтобы исправить это?

<Button
    android:id="@+id/show_in_map_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="32dp"
    android:layout_marginEnd="8dp"
    android:background="@drawable/round_details_button"
    android:drawableStart="@drawable/location_btn"
    android:drawableTint="@android:color/white"
    android:fontFamily="@font/montserrat_medium"
    android:paddingStart="15dp"
    android:paddingEnd="15dp"
    android:text="@string/show_in_map_button"
    android:textColor="@android:color/white"
    android:textSize="14sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/place_description" />

PS: я видел несколько постов, касающихся этой проблемы, которые пытались решить ее в коде, используя ScaleDrawable, но это не сработало для меня.

result

Ответы [ 5 ]

1 голос
/ 04 июля 2019

Есть старый подход, который работает для меня.

Я просто создаю границы и устанавливаю это для моей кнопки. Таким образом, любой объект, который я прикрепляю к моему объекту, принимает размеры границ.

drawable.bounds = Rect(0, 0, 80, 80) // in this case, the drawable is going to be 80 x 80
button.setCompoundDrawables(drawable, null, null, null)

Надеюсь, это поможет. Веселого кодирования!

0 голосов
/ 09 июля 2019

Чтобы иметь drawable вашего нестандартного размера в Button или TextView, вы можете создать собственный класс, как показано ниже, с некоторыми стилевыми атрибутами:

  1. create attrs.xml файл в папке res -> values ​​ и создание стиля как показано ниже:

    <resources>
        <declare-styleable name="DrawableButton">
            <attr name="drawableSize" format="dimension" />
            <attr name="drawableScale" format="float" />
        </declare-styleable>
    </resources>
    
  2. Тогдасоздайте класс с именем DrawableButton, как показано ниже:

    class DrawableButton : AppCompatButton {
        internal var drawableSize: Float? = null
        internal var drawableScale: Float = 1F
    
        constructor(context: Context?) : this(context, null)
    
        constructor(context: Context?, attr: AttributeSet?) : this(context, attr, android.R.style.Widget_Button)
    
        constructor(context: Context?, attr: AttributeSet?, defStyle: Int) : super(context, attr, defStyle) {
            loadAttrs(context, attr)
            initDrawablesForResize()
        }
    
        private fun loadAttrs(context: Context?, attrs: AttributeSet?) {
            if (context != null && attrs != null) {
                val typedArray: TypedArray? = context.obtainStyledAttributes(attrs, R.styleable.DrawableButton, 0, 0)
                typedArray?.let { arr ->
                    for (index in 0 until arr.indexCount) {
                        assignValueToVariables(arr, index)
                    }
                }
                typedArray?.recycle()
            }
        }
    
        private fun assignValueToVariables(arr: TypedArray, index: Int) {
            val resourceId = arr.getIndex(index)
            when (resourceId) {
                R.styleable.DrawableButton_drawableSize -> {
                    drawableSize = arr.getDimension(resourceId, Math.min(measuredHeight, measuredWidth).toFloat())
                }
                R.styleable.DrawableButton_drawableScale -> {
                    drawableScale = arr.getFloat(resourceId, 1F)
                }
                else -> {
                    // Left out because "Unused"
                }
            }
        }
    
        private fun initDrawablesForResize() {
            val size = compoundDrawablesRelative.size
            val drawableList = ArrayList<Drawable?>(size)
            for (index in 0 until size) {
                val drawable = compoundDrawablesRelative[index]
                if (drawable != null) {
                    if (drawableSize == null) {
                        drawableSize = Math.min(drawable.intrinsicHeight.times(drawableScale), drawable.intrinsicWidth.times(drawableScale))
                    }
                    drawable.setBounds(
                        0,
                        0,
                        drawableSize!!.toInt(),
                        drawableSize!!.toInt()
                    )
                    drawableList.add(index, drawable)
                } else {
                    drawableList.add(index, null)
                }
            }
            this.setCompoundDrawablesRelative(drawableList[0], drawableList[1], drawableList[2], drawableList[3])
        }
    
        override fun performClick(): Boolean {
            super.performClick()
            return true
        }
    }
    
  3. Перестройте проект один раз, и теперь вы готовы использовать этот класс DrawableButton в вашем xmlфайл, как показано ниже:

    <your_package_name_where_this_class_is.DrawableButton
        android:id="@+id/show_in_map_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/round_details_button"
        android:drawableStart="@drawable/location_btn"
        android:drawableTint="@android:color/white"
        android:fontFamily="@font/montserrat_medium"
        android:paddingStart="15dp"
        android:paddingEnd="15dp"
        android:text="@string/show_in_map_button"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/place_description" />
    

Теперь вы можете использовать drawableSize или drawableScale атрибутов из app: или другое пользовательское пространство имен для масштабирования ваших элементов рисования в drawableStart, drawableEnd, drawableTop или drawableBottom.Он работает как с векторами , так и с растровыми изображениями .

Примечание: Это не работает с drawableLeft & drawableRight из-за методаsetCompoundDrawablesRelative(), который использует начальные и конечные атрибуты для рисования.Для работы с левым и правым рисованием замените этот метод на метод setCompoundDrawables().

0 голосов
/ 05 июля 2019

Попробуйте использовать также растягиваемые отступы.

0 голосов
/ 04 июля 2019

Одним из возможных решений было бы обернуть ваш ресурс в drawable и определить там высоту и ширину, а затем использовать его в вашем атрибуте android:drawableStart.Это работает только с API 23 и выше, но, к примеру, не приведет к краху вашего приложения на API 21.Вы можете взглянуть на пример ниже:

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

  <item
      android:drawable="@drawable/location_btn"
      android:width="@dimen/icon_size"
      android:height="@dimen/icon_size" />

</layer-list>
0 голосов
/ 01 июля 2019

Вы уже пробовали это, Вы можете масштабировать свой чертеж таким образом.

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/logo"
    android:scaleGravity="center_vertical|center_horizontal"
    android:scaleHeight="80%"
    android:scaleWidth="80%" />

Вы также можете масштабировать свой чертеж таким образом

android:scaleType="fitXY"
...