按钮中的 drawableStart 无法正确缩放
drawableStart in button doesn't scale correctly
我在下面的 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。
<?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"
有一种旧方法对我有用。
我只是创建边界并将其设置为我的按钮。这样我附加到我的可绘制对象的任何可绘制对象都采用边界的尺寸。
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)
希望对您有所帮助。编码愉快!
一种可能的解决方案是将您的资源包装在一个可绘制对象中并在那里定义高度和宽度,然后在您的 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>
也尝试使用可绘制的填充。
要在 Button
或 TextView
中拥有自定义大小的 drawable,您可以创建自定义 class,如下所示,带有一些可设置样式的属性:
在 res -> values 文件夹中创建 attrs.xml 文件并创建 风格化 如下所示:
<resources>
<declare-styleable name="DrawableButton">
<attr name="drawableSize" format="dimension" />
<attr name="drawableScale" format="float" />
</declare-styleable>
</resources>
然后创建名为 DrawableButton
的 class,如下所示:
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
}
}
重新构建项目一次,现在您可以在 xml 中使用此 DrawableButton
class文件如下:
<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
来自 [=19 的属性=] 或其他自定义命名空间以在 drawableStart
、drawableEnd
、drawableTop
或 drawableBottom
中缩放您的可绘制对象。它适用于 矢量 以及 光栅图像 .
Note : It doesn't work with drawableLeft & drawableRight, due to method setCompoundDrawablesRelative()
which uses start and end attrs for drawables. To work with left and right drawables replace this method with setCompoundDrawables()
method.
我在下面的 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。
<?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"
有一种旧方法对我有用。
我只是创建边界并将其设置为我的按钮。这样我附加到我的可绘制对象的任何可绘制对象都采用边界的尺寸。
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)
希望对您有所帮助。编码愉快!
一种可能的解决方案是将您的资源包装在一个可绘制对象中并在那里定义高度和宽度,然后在您的 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>
也尝试使用可绘制的填充。
要在 Button
或 TextView
中拥有自定义大小的 drawable,您可以创建自定义 class,如下所示,带有一些可设置样式的属性:
在 res -> values 文件夹中创建 attrs.xml 文件并创建 风格化 如下所示:
<resources> <declare-styleable name="DrawableButton"> <attr name="drawableSize" format="dimension" /> <attr name="drawableScale" format="float" /> </declare-styleable> </resources>
然后创建名为
DrawableButton
的 class,如下所示: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 } }
重新构建项目一次,现在您可以在 xml 中使用此
DrawableButton
class文件如下:<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
来自 [=19 的属性=] 或其他自定义命名空间以在 drawableStart
、drawableEnd
、drawableTop
或 drawableBottom
中缩放您的可绘制对象。它适用于 矢量 以及 光栅图像 .
Note : It doesn't work with drawableLeft & drawableRight, due to method
setCompoundDrawablesRelative()
which uses start and end attrs for drawables. To work with left and right drawables replace this method withsetCompoundDrawables()
method.