当前位置: 首页 > article >正文

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>


http://www.kler.cn/a/456151.html

相关文章:

  • --spring.profiles.active=prod
  • docker-开源nocodb,使用已有数据库
  • 6-Gin 路由详解 --[Gin 框架入门精讲与实战案例]
  • Excel将混乱的多行做成1列
  • UE(虚幻)学习(三) UnrealSharp插件中调用非托管DLL
  • SpringBoot配置文件、热部署、YAML语法、配置文件值注入
  • Python学生管理系统(MySQL)
  • default、delete 和 explicit
  • Spark生态圈
  • 在FreeBSD或Ubuntu平台仿真RISCV64位版本FreeBSD系统相关技术文档
  • 基于Spring Boot + Vue3实现的在线商品竞拍管理系统源码+文档
  • 记录命令行操作树莓派Wifi的方式
  • FAISS进行高效的向量检索 原理详解
  • MyBatis中XML文件的模板
  • Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
  • xadmin后台首页增加一个导入数据按钮
  • CA系统的设计(CA证书生成,吊销,数字签名生成)
  • 关于Qt::BlockingQueuedConnection的死锁问题
  • Fastbot-iOS(iOS monkey)schema参数的指定方式
  • 【工具变量】地级市减碳重视程度及减碳词频数据(2003-2024年)
  • Mybatis-Plus updateById 方法更新无效及空值处理
  • 【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
  • mprpc框架代码详解
  • 【HarmonyOS之旅】ArkTS语法(二)->动态构建UI元素
  • Spring Boot介绍、入门案例、环境准备、POM文件解读
  • UE(虚幻)学习(一) UE5.3.2和VS2022的安装以及遇到的问题和一些CS8604、CA2017报错问题.