Android——自定义按钮button
项目中经常高频使用按钮,要求:可设置颜色,有圆角且有按下效果的Button
一、自定义按钮button
button的代码为
package com.fslihua.clickeffect
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable
import android.util.AttributeSet
import android.view.Gravity
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatButton
@SuppressLint("ResourceType")
class ShapeButton @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
AppCompatButton(context!!, attrs, defStyleAttr) {
private val normal_color: Int
private val pressed_color: Int
private val enabled_color: Int
private val gravity: Int
private val radius_size: Int
init {
val ta = getContext().obtainStyledAttributes(attrs, R.styleable.ShapeButton)
normal_color = ta.getColor(R.styleable.ShapeButton_normal_color, Color.parseColor("#FF3333"))
pressed_color = ta.getColor(R.styleable.ShapeButton_pressed_color, Color.parseColor("#CC3333"))
enabled_color = ta.getColor(R.styleable.ShapeButton_enabled_color, Color.GRAY)
radius_size = ta.getDimension(R.styleable.ShapeButton_radius_size, dip2px(4f).toFloat()).toInt()
gravity = ta.getInt(R.styleable.ShapeButton_android_gravity, Gravity.CENTER)
// int textColor = attrs.getAttributeIntValue(
// "http://schemas.android.com/apk/res/android", "textColor", Color.WHITE);
// setTextColor(textColor);
ta.recycle()
val tar = getContext().obtainStyledAttributes(
attrs,
intArrayOf(android.R.attr.textColor, android.R.attr.paddingTop, android.R.attr.paddingBottom)
)
if (tar != null) {
setTextColor(tar.getColor(0, Color.WHITE))
setPadding(6, tar.getDimension(1, 8f).toInt(), 6, tar.getDimension(2, 8f).toInt())
}
setGravity(gravity)
tar.recycle()
init()
}
override fun setTextColor(@ColorInt color: Int) {
super.setTextColor(color)
}
private fun init() {
setBackgroundDrawable(
getStateListDrawable(
getSolidRectDrawable(radius_size, pressed_color),
getSolidRectDrawable(radius_size, normal_color)
)
)
setOnClickListener { }
}
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
super.setPadding(
dip2px(left.toFloat()),
dip2px(top.toFloat()),
dip2px(right.toFloat()),
dip2px(bottom.toFloat())
)
}
/**
* 背景选择器
*
* @param pressedDrawable 按下状态的Drawable
* @param normalDrawable 正常状态的Drawable
* @return 状态选择器
*/
fun getStateListDrawable(pressedDrawable: Drawable?, normalDrawable: Drawable?): StateListDrawable {
val stateListDrawable = StateListDrawable()
stateListDrawable.addState(
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed),
pressedDrawable
)
stateListDrawable.addState(intArrayOf(android.R.attr.state_enabled), normalDrawable)
//设置不能用的状态
//默认其他状态背景
val gray = getSolidRectDrawable(radius_size, enabled_color)
stateListDrawable.addState(intArrayOf(), gray)
return stateListDrawable
}
private fun dip2px(dpValue: Float): Int {
val scale = resources
.displayMetrics.density
return (dpValue * scale + 0.5f).toInt()
}
companion object {
/**
* 得到实心的drawable, 一般作为选中,点中的效果
*
* @param cornerRadius 圆角半径
* @param solidColor 实心颜色
* @return 得到实心效果
*/
fun getSolidRectDrawable(cornerRadius: Int, solidColor: Int): GradientDrawable {
val gradientDrawable = GradientDrawable()
// 设置矩形的圆角半径
gradientDrawable.cornerRadius = cornerRadius.toFloat()
// 设置绘画图片色值
gradientDrawable.setColor(solidColor)
// 绘画的是矩形
gradientDrawable.gradientType = GradientDrawable.RADIAL_GRADIENT
return gradientDrawable
}
}
}
attrs.xml的代码为:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ShapeButton">
<!--按下的颜色-->
<attr name="pressed_color" format="color" />
<!--正常状态颜色-->
<attr name="normal_color" format="color" />
<!--不可用的颜色-->
<attr name="enabled_color" format="color" />
<!--按钮圆角半径-->
<attr name="radius_size" format="dimension" />
<!--gravity-->
<attr name="android:gravity" />
</declare-styleable>
</resources>
在xml里使用:
<com.fslihua.clickeffect.ShapeButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击ss"
android:textSize="8sp"
app:radius_size="8dp"
app:normal_color="@color/red"
app:pressed_color="@color/black_25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
二、使用系统默认的按钮AppCompatButton
效果图:
xml中的代码为:
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:text="点击"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@drawable/button_select"
android:theme="@style/AppTheme"/>
AppTheme主题:
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="pressedColor">@color/black_25</item> <!-- 按下时的红色 -->
<item name="normalColor">@color/red</item> <!-- 正常时的绿色 -->
<item name="radiusSize">20dp</item> <!-- 10dp -->
</style>
</resources>
button_select.xml的代码为(drawable):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 按钮被按下时的背景颜色 -->
<item android:state_pressed="true">
<shape>
<!-- 在主题里进行设置具体的值 -->
<solid android:color="?attr/pressedColor" />
<corners android:radius="?attr/radiusSize" />
</shape>
</item>
<!-- 按钮正常状态的背景颜色 -->
<item>
<shape>
<!-- 在主题里进行设置具体的值 -->
<solid android:color="?attr/normalColor" />
<corners android:radius="?attr/radiusSize" />
</shape>
</item>
</selector>
attrs.xml的代码为:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomBt">
<attr name="pressedColor" format="color" />
<attr name="normalColor" format="color" />
<!--按钮圆角半径-->
<attr name="radiusSize" format="dimension" />
</declare-styleable>
</resources>