当前位置:

首页 > 系统应用 > 2.3.3 Button(按钮)与ImageButton(图像按钮)

2.3.3 Button(按钮)与ImageButton(图像按钮)

本节引言: 这一段来聊 Android 基本控件里的两种按钮:Button 普通按钮和 ImageButton 图像按钮。ImageButton 的用法其实和 Button 大体一致;至于和图片显示相关的部分,后面讲到 ImageView 时也会覆盖到,所以这一节把重点放在 Button 上就够了。

本文目录

    本节引言:

    这一段来聊 Android 基本控件里的两种按钮:Button 普通按钮和 ImageButton 图像按钮。ImageButton 的用法其实和 Button 大体一致;至于和图片显示相关的部分,后面讲到 ImageView 时也会覆盖到,所以这一节把重点放在 Button 上就够了。还有一点别忽略,Button 本质上是 TextView 的子类,因此 TextView 上不少属性,同样可以直接用在 Button 上。回到实际开发,Button 最常见的处理,无非就是围绕几种状态做样式切换:按下时一个颜色,抬起后另一个颜色,禁用时再显示另一种颜色。说白了,这类效果通常就是借助 StateListDrawable 这种 Drawable 资源来完成,也就是单独写一个 drawable 资源文件。铺垫先到这里,下面直接进入本节内容。

    1.StateListDrawable简介:

    StateListDrawable是Drawable资源的一种,可以根据不同的状态,设置不同的图片效果,关键节点 < selector >,我们只需要将Button的background属性设置为该drawable资源即可轻松实现,按下 按钮时不同的按钮颜色或背景!

    我们可以设置的属性:

    • drawable:引用的Drawable位图,我们可以把他放到最前面,就表示组件的正常状态~
    • state_focused:是否获得焦点
    • state_window_focused:是否获得窗口焦点
    • state_enabled:控件是否可用
    • state_checkable:控件可否被勾选,eg:checkbox
    • state_checked:控件是否被勾选
    • state_selected:控件是否被选择,针对有滚轮的情况
    • state_pressed:控件是否被按下
    • state_active:控件是否处于活动状态,eg:slidingTab
    • state_single:控件包含多个子控件时,确定是否只显示一个子控件
    • state_first:控件包含多个子控件时,确定第一个子控件是否处于显示状态
    • state_middle:控件包含多个子控件时,确定中间一个子控件是否处于显示状态
    • state_last:控件包含多个子控件时,确定最后一个子控件是否处于显示状态

    2.实现按钮的按下效果:

    好的,先准备三个图片背景,一般我们为了避免按钮拉伸变形都会使用.9.png作为按钮的drawable! 先来看下 运行效果图:

    代码实现:

    
    
        
        
        
    

    布局文件:activity_main.xml

    MainActivity.ja va:

    public class MainActivity extends Activity {
    private Button btnOne,btnTwo;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            btnOne = (Button) findViewById(R.id.btnOne);
            btnTwo = (Button) findViewById(R.id.btnTwo);
            btnTwo.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(btnTwo.getText().toString().equals("按钮不可用")){
                        btnOne.setEnabled(false);
                        btnTwo.setText("按钮可用");
                    }else{
                        btnOne.setEnabled(true);
                        btnTwo.setText("按钮不可用");
                    }
                }
            });
        }
    }

    3.使用颜色值绘制圆角按钮

    很多时候,手头未必有美工支持;要么不会用PS、秀图工具之类的软件,要么就是单纯不想自己折腾做图。其实这种场景下,完全可以直接用代码把按钮背景写出来,颜色想怎么配就怎么配。下面就来做一个带圆角的按钮背景。这里会用到另一个drawable资源:ShapeDrawable,先不展开细讲,后面会把每一种drawable单独说明清楚。眼下先会用就够了,本质上也只是把EditText的Background属性改一下而已,这里就只贴drawable资源。

    先看下效果图:

    bbuton_danger_rounded.xml:

    
    
    
                
                
                
            
    
            
                
                
            
    
                
                
                
            
    

    color.xml:

    
    
        #ffd2322d
        #ffd43f3a
        #a5d9534f
        #a5d43f3a
        #ffd9534f
        #FFFFFF
    

    dimens.xml:

    5dp

    4.实现Material Design水波效果的Button

    如果你的Android手机是5.0以上的系统,相信对下面这种按钮点击效果并不会陌生:

    实现效果图:

    快的那个是按下后的效果,慢的是长按后的效果!

    实现逻辑:

    1.我们继承ImageButton,当然你可以换成Button或者View,这里笔者想把龟放到中间才继承ImageButton

    2.首先,创建两个Paint(画笔)对象,一个绘制底部背景颜色,一个绘制波纹扩散的

    3.接着计算最大半径,开始半径每隔一段时间递增一次,直到等于最大半径,然后重置状态!

    PS:大概的核心,刚学可能对自定义View感到陌生,没事,这里了解下即可,以后我们会讲,当然 你可以自己扣扣,注释还是蛮详细的~

    实现代码:

    自定义ImageButton:MyButton.ja va

    package demo.com.jay.buttondemo;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.os.SystemClock;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.ViewConfiguration;
    import android.widget.ImageButton;
    /**
     * Created by coder-pig on 2015/7/16 0016.
     */
    public class MyButton extends ImageButton {
    private static final int INVALIDATE_DURATION = 15;     //每次刷新的时间间隔
        private static int DIFFUSE_GAP = 10;                  //扩散半径增量
        private static int TAP_TIMEOUT;                         //判断点击和长按的时间
    private int viewWidth, viewHeight;                   //控件宽高
        private int pointX, pointY;                          //控件原点坐标(左上角)
        private int maxRadio;                             //扩散的最大半径
        private int shaderRadio;                        //扩散的半径
    private Paint bottomPaint, colorPaint;          //画笔:背景和水波纹
        private boolean isPushButton;                 //记录是否按钮被按下
    private int eventX, eventY;                  //触摸位置的X,Y坐标
        private long downTime = 0;                 //按下的时间
    public MyButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            initPaint();
            TAP_TIMEOUT = ViewConfiguration.getLongPressTimeout();
        }
    /*
        * 初始化画笔
        * */
        private void initPaint() {
            colorPaint = new Paint();
            bottomPaint = new Paint();
            colorPaint.setColor(getResources().getColor(R.color.reveal_color));
            bottomPaint.setColor(getResources().getColor(R.color.bottom_color));
        }
    @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (downTime == 0) downTime = SystemClock.elapsedRealtime();
                    eventX = (int) event.getX();
                    eventY = (int) event.getY();
                    //计算最大半径:
                    countMaxRadio();
                    isPushButton = true;
                    postInvalidateDelayed(INVALIDATE_DURATION);
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    if(SystemClock.elapsedRealtime() - downTime < TAP_TIMEOUT){
                        DIFFUSE_GAP = 30;
                        postInvalidate();
                    }else{
                        clearData();
                    }
                    break;
            }
            return super.onTouchEvent(event);
        }
    @Override
        protected void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
            if(!isPushButton) return; //如果按钮没有被按下则返回
            //绘制按下后的整个背景
            canvas.drawRect(pointX, pointY, pointX + viewWidth, pointY + viewHeight, bottomPaint);
            canvas.sa ve();
            //绘制扩散圆形背景
            canvas.clipRect(pointX, pointY, pointX + viewWidth, pointY + viewHeight);
            canvas.drawCircle(eventX, eventY, shaderRadio, colorPaint);
            canvas.restore();
            //直到半径等于最大半径
            if(shaderRadio < maxRadio){
                postInvalidateDelayed(INVALIDATE_DURATION,
                        pointX, pointY, pointX + viewWidth, pointY + viewHeight);
                shaderRadio += DIFFUSE_GAP;
            }else{
                clearData();
            }
        }
    /*
            * 计算最大半径的方法
            * */
        private void countMaxRadio() {
            if (viewWidth > viewHeight) {
                if (eventX < viewWidth / 2) {
                    maxRadio = viewWidth - eventX;
                } else {
                    maxRadio = viewWidth / 2 + eventX;
                }
            } else {
                if (eventY < viewHeight / 2) {
                    maxRadio = viewHeight - eventY;
                } else {
                    maxRadio = viewHeight / 2 + eventY;
                }
            }
        }
    /*
        * 重置数据的方法
        * */
        private void clearData(){
            downTime = 0;
            DIFFUSE_GAP = 10;
            isPushButton = false;
            shaderRadio = 0;
            postInvalidate();
        }
    @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            this.viewWidth = w;
            this.viewHeight = h;
        }
    }
    
    

    color.xml:

    
    
        #FFFFFF
        #3086E4
        #40BAF8
    

    activity_main.xml:

    
    
    

    源码下载(AS工程的哦):ButtonDemo.zip

    本节小结:

    本节给大家介绍了Button在实际开发中的一些用法,可能有些东西我们还没学,这里 知道下即可,后面学到自然会深入讲解,谢谢~

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    系统应用
    相关文章 更多
    Yandex浏览器官网登录与在线体验入口
    Yandex浏览器官网登录与在线体验入口

    Yandex浏览器官方网站登录入口是https://www.yondex.net/,提供多语言下载、账户同步、广告拦截、Turbo模式及隐私保护等功能,支持跨设备数据同步与安全浏览。

    2026年AO3镜像最新地址及稳定入口
    2026年AO3镜像最新地址及稳定入口

    ao3镜像2026最新入口包括主站archiveofourown.org、镜像站ao3mirror.com和xiaozhan.icu,建议收藏备用并根据网络情况切换使用。

    Win10搜索不到蓝牙耳机的排查与连接方法
    Win10搜索不到蓝牙耳机的排查与连接方法

    面向在Windows 10系统中无法发现蓝牙耳机的用户,本文提供从耳机配对模式到系统设置的完整排查路径。首先确保耳机已充电并进入可被搜索的配对状态,断开与其他设备的连接;随后在Win10设置中开启蓝牙并添加设备。若蓝牙开关缺失或适配器异常,需通过设备管理器检查驱动状态并更新,以恢复正常的蓝牙音频设备识别功能。

    Win10蓝牙耳机麦克风没声音?检查输入设备与权限设置
    Win10蓝牙耳机麦克风没声音?检查输入设备与权限设置

    面向在Windows 10系统中遇到蓝牙耳机能听声但无法录音的用户,本文解决因输入通道选择错误、隐私权限关闭或语音连接缺失导致的麦克风无声问题。关键步骤包括:在系统声音设置中正确选择Headset Microphone或Hands-Free AG Audio作为输入设备;在隐私设置中开启应用访问麦克风权限;确认蓝牙状态包含语音连接而非仅音乐连接,必要时重新配对或更新驱动。注意Stereo模式不支持麦克风输入,勿为音质牺牲通话功能。

    Win11打开服务管理器的两种方法:运行命令与计算机管理
    Win11打开服务管理器的两种方法:运行命令与计算机管理

    面向需要在Windows 11中查看或配置系统服务的用户,本文提供两种快速进入服务管理器的路径。一是通过Win+R运行services.msc直接打开,适合快速访问;二是从开始菜单进入计算机管理,再展开服务和应用程序找到服务列表,适合在统一管理界面中操作。文中说明查看状态通常无需特殊权限,而修改服务设置可能需要管理员账户,帮助用户根据实际需求选择合适入口。

    fences怎么彻底删除 清理残留文件
    fences怎么彻底删除 清理残留文件

    想知道Fences怎么彻底删除?本教程详解Windows 11下卸载Fences、使用官方Purge工具清理残留、删除布局备份及日志的步骤,助您干净移除软件并恢复桌面原生体验。

    Win11打开组策略的命令及家庭版无法使用说明
    Win11打开组策略的命令及家庭版无法使用说明

    面向需要在Windows 11中调整系统设置的用户,介绍通过运行命令gpedit.msc快速打开本地组策略编辑器的方法。该功能仅内置于专业版、企业版和教育版,家庭版通常不包含此工具,运行报错并非系统故障。本文详解正确的命令输入格式、界面确认方式以及通过任务栏搜索的替代路径,并指导家庭版用户如何查看系统版本以选择对应的设置入口或升级方案。

    Win11家庭版找不到组策略编辑器怎么办
    Win11家庭版找不到组策略编辑器怎么办

    面向使用Windows 11家庭版或家庭中文版的用户,解决运行gpedit.msc提示找不到文件的问题。该现象源于版本功能限制,修改文件名或重装同版本系统均无效。本文指导用户先通过“设置-关于”确认系统版本,日常配置优先在“设置”应用中完成;若确需本地组策略功能,建议通过官方渠道升级至专业版,并警示避免使用来源不明的第三方安装工具。

    fences怎么退出 关闭后台运行程序
    fences怎么退出 关闭后台运行程序

    想让 Fences 暂时停止接管桌面?本文详解 Windows 11/10 下关闭 Fences 总开关、禁用开机启动及验证后台状态的操作步骤,区分临时停用与彻底卸载,确保桌面文件安全。

    电脑黑屏图片有哪些类型?纯黑壁纸与故障画面辨别方法
    电脑黑屏图片有哪些类型?纯黑壁纸与故障画面辨别方法

    分不清电脑黑屏是设置了纯黑壁纸还是系统故障?本文详解纯黑壁纸的视觉特征与故障黑屏的区别,提供Windows和Mac系统的纯黑壁纸设置方法,助你快速判断屏幕状态。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。