Bootstrap

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>

;