【问题标题】:drawableStart in button doesn't scale correctly按钮中的 drawableStart 无法正确缩放
【发布时间】:2019-06-30 20:57:09
【问题描述】:

我在下面的Button 中有一个可绘制的drawableStart 图标,但它不能正确缩放。我能做些什么来纠正这个问题?

<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" />

P.S:我看过一些关于这个问题的帖子,它们试图在代码中使用 ScaleDrawable 解决它,但这对我不起作用。

【问题讨论】:

  • 您可以为此制作自定义按钮吗?我过去遇到过同样的问题,最终为同样的问题创建了自定义按钮。
  • 你希望按钮和drawable如何显示在里面???发布屏幕截图或说明。 SS会很棒!
  • @JeelVankhede 我以前从未尝试过,所以为什么不:)

标签: android android-drawable android-button


【解决方案1】:

有一种旧方法对我有用。

我只是创建边界并将其设置到我的按钮。这样,我附加到我的可绘制对象的任何可绘制对象都采用边界的尺寸。

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)

我希望这会有所帮助。编码愉快!

【讨论】:

  • 做到了。只需要使用 drawable.setBounds(new Rect(0,0,80,80));感谢您的帮助,这将在以后派上用场。
【解决方案2】:

你试过了吗,你可以像这样缩放你的drawable。

<?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%" />

你也可以像这样缩放你的drawable

android:scaleType="fitXY"

【讨论】:

  • 我需要在代码中的某个地方使用它才能生效吗?如果需要,在哪里?
  • 打开 location_btn drawable 并添加 android:scaleHeight="80%" android:scaleWidth="80%" this 来缩放它
  • 好的,如果 drawable 不是 svg,那么您可以将其添加到上面的代码中或尝试其他可用的 scaleType android:scaleType="fitXY"
  • 我不认为android:scaleType="fitXY"Button 中有效,我之前在另一篇文章中尝试过作为解决方案,但它没有做任何事情。
【解决方案3】:

一种可能的解决方案是将您的资源包装在一个可绘制对象中并在那里定义高度和宽度,然后在您的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>

【讨论】:

    【解决方案4】:

    也尝试使用可绘制的填充。

    【讨论】:

      【解决方案5】:

      要在ButtonTextViewdrawable 您的自定义大小,您可以使用一些样式属性创建如下自定义类:

      1. res -> values 文件夹中创建 attrs.xml 文件并创建 styleable,如下所示:

        <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. 重建项目一次,现在您就可以在 xml 文件中使用这个 DrawableButton 类了,如下所示:

        <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" />
        

      现在您可以使用 app: 中的 drawableSizedrawableScale 属性或其他自定义命名空间来缩放您的可绘制对象 drawableStartdrawableEnddrawableTopdrawableBottom。它适用于矢量以及光栅图像

      注意:它不适用于 drawableLeft 和 drawableRight,因为 setCompoundDrawablesRelative() 方法使用了可绘制对象的开始和结束属性。要使用左右可绘制对象,请将此方法替换为 setCompoundDrawables() 方法。

      【讨论】:

        猜你喜欢
        • 2018-06-22
        • 2019-05-18
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多