Android学习之路(5) UI控件之Button (按钮)与 ImageButton (图像按钮)

news2024/9/25 9:37:14

本节引言:

今天给大家介绍的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! 先来看下 运行效果图:

代码实现:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/ic_course_bg_fen"/>
    <item android:state_enabled="false" android:drawable="@drawable/ic_course_bg_pressed"/>
    <item android:drawable="@drawable/ic_course_bg_cheng"/>
</selector>

布局文件:activity_main.xml

<Button
        android:id="@+id/btnOne"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:background="@drawable/btn_bg1"
        android:text="按钮"/>
    
    
    <Button
        android:id="@+id/btnTwo"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:text="按钮不可用"/>

MainActivity.java:

public class MainActivity extends Activity {

    private Button btnOne,btnTwo;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        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:

<?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="@color/bbutton_danger_pressed" />
            <stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
            <corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
        </shape></item>
        
    
    <item android:state_enabled="false"><shape>
        <solid android:color="@color/bbutton_danger_disabled" />
            <stroke android:width="1dp" android:color="@color/bbutton_danger_disabled_edge" />
            <corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
        </shape></item>
        

    <item><shape>
            <solid android:color="@color/bbutton_danger" />
            <stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
            <corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
        </shape></item>
    
        
</selector>

color.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="bbutton_danger_pressed">#ffd2322d</color>
    <color name="bbutton_danger_edge">#ffd43f3a</color>
    <color name="bbutton_danger_disabled">#a5d9534f</color>
    <color name="bbutton_danger_disabled_edge">#a5d43f3a</color>
    <color name="bbutton_danger">#ffd9534f</color>
    <color name="text_font_white">#FFFFFF</color>
</resources>

dimens.xml:

<dimen name="bbuton_rounded_corner_radius">5dp</dimen>

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

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

实现效果图:

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

实现逻辑:

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

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

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

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

实现代码:

自定义ImageButton:MyButton.java

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.save();
        //绘制扩散圆形背景
        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;
    }
}

<code>
<p><b>color.xml:</b></p>
<pre>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="reveal_color">#FFFFFF</color>
    <color name="bottom_color">#3086E4</color>
    <color name="bottom_bg">#40BAF8</color>
</resources>
activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <demo.com.jay.buttondemo.MyButton
        android:id="@+id/myBtn"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:src="@mipmap/ic_tur_icon"
        android:background="@color/bottom_bg"
        android:scaleType="center"/>

</RelativeLayout>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/899977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑客、骇客、红蓝对抗中几百种渗透测试工具集合全精华最新整理以及各类CTF资料

黑客、骇客、红蓝对抗中几百种渗透测试工具集合全精华最新整理以及各类CTF资料。 WebGoat漏洞练习平台 https://github.com/WebGoat/WebGoat webgoat-legacy漏洞练习平台 https://github.com/WebGoat/WebGoat-Legacy zvuldirll漏洞练习平台 https://github.com/710leo/ZVul…

OJ练习第153题——加油站

加油站 力扣链接&#xff1a;134. 加油站 题目描述 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xf…

Postman软件基本用法:浏览器复制请求信息并导入到软件从而测试、发送请求

本文介绍在浏览器中&#xff0c;获取网页中的某一个请求信息&#xff0c;并将其导入到Postman软件&#xff0c;并进行API请求测试的方法。 Postman是一款流行的API开发和测试工具&#xff0c;它提供了一个用户友好的界面&#xff0c;用于创建、测试、调试和文档化API。本文就介…

最强自动化测试框架Playwright(37)-网络

介绍 Playwright 提供 API 来监控和修改浏览器网络流量&#xff0c;包括 HTTP 和 HTTPS。页面执行的任何请求&#xff0c;包括 XHR 和获取请求&#xff0c;都可以被跟踪、修改和处理。 模拟接口 查看我们的 API 模拟指南&#xff0c;了解有关如何 模拟 API 请求&#xff0c…

Python_11 类的方法

一、查缺补漏 1. 实例方法必须用类实例化对象()来调用&#xff0c;用类来调用时会执行&#xff0c;但是self中不是实例化类地址而是传的字符串 二、类中的方法 1. 实例方法 1. 定义在类里面的普通方法(函数) 2. 第一个参数必须是类实例&#xff0c;在方法调用的时候会自动…

RHCE——一、安装部署及例行性工作

RHCE 一、网络服务1、准备工作2、RHEL9操作系统的安装部署3、配置并优化RHEL9操作系统4、网络配置5、修改网络连接 二、例行性工作1、单一执行的例行性工作2、循环执行的例行性工作 三、书写定时任务的注意事项四、系统级别的计划任务五、实验1、实验一&#xff1a;编写脚本tes…

OJ练习第152题——分割回文串 II

分割回文串 II 力扣链接&#xff1a;132. 分割回文串 II 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 Java代码 class Solution {public int minCut(String s) {int n s.leng…

python基础5——正则、数据库操作

文章目录 一、数据库编程1.1 connect()函数1.2 命令参数1.3 常用语句 二、正则表达式2.1 匹配方式2.2 字符匹配2.3 数量匹配2.4 边界匹配2.5 分组匹配2.6 贪婪模式&非贪婪模式2.7 标志位 一、数据库编程 可以使用python脚本对数据库进行操作&#xff0c;比如获取数据库数据…

C++系列-引用

引用 引用的基本使用引用的起源引用的语法引用的本质引用的注意事项引用和指针 引用作为函数参数引用作为函数的返回值常量引用其它用返回值方式调用函数&#xff08;case 1&#xff09;用函数的返回值初始化引用的方式调用函数&#xff08;case 2&#xff09;用返回引用的方式…

No113.精选前端面试题,享受每天的挑战和学习

文章目录 怎样理解 Vue 的单向数据流说下MVVM说下cookieVue 的性能优化Cookie、localStorage 和 sessionStorageVue中的computed属性和watch属性有什么区别&#xff1f; 怎样理解 Vue 的单向数据流 在Vue中&#xff0c;单向数据流是指数据在Vue组件中的传递方向是有限制的&…

使用Vscode调试shell脚本

在vcode中安装bash dug插件 在vcode中添加launch.json配置&#xff0c;默认就好 参考&#xff1a;http://www.rply.cn/news/73966.html 推荐插件&#xff1a; shellman(支持shell,智能提示) shellcheck(shell语法检查) shell-format(shell格式化)

【文化课学习笔记】【化学】金属及其化合物

【化学】必修一&#xff1a;金属及其化合物 钠及其化合物 钠单质 物理性质 颜色&#xff1a;银白色&#xff0c;有金属光泽&#xff1b;密度&#xff1a;\(\mathrm{\rho_{H_2O}>\rho_{Na}>\rho_{煤油}}\)(钠可以在煤油中进行保存)&#xff1b;熔点&#xff1a;低于 \(100…

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)。 一个新项目,后端使用 PHP 实现,前端不做路由,提供一个模板,由后端路由控制。 Route::get(pages/{name}, [\App\Http\Controllers\ResourceController::class, getResourceVersion])

如何在工作中利用AIGC提质增效?

引言 人工智能技术快速发展&#xff0c;以 ChatGPT 为代表的新的人工智能语言模型的出现与更迭&#xff0c;引发人们极大的兴奋和关注。越来越多的企业开始将 AI 技术应用到生产流程&#xff0c;以提高工作效率和生产力。AIGC&#xff08;AI Generated Content&#xff09;是人…

文本生成解码策略 Beam Search, top_k, temperature

一、从Greedy Search到Beam Search Greedy search是指在每个t时刻选择下一个词时&#xff0c;根据 wtargmaxwP(w|w1:t−1)选择概率最高的词。 以上图为例&#xff1a; 从单词“The”开始&#xff0c;算法在选择下一个词时&#xff0c;贪心的选择了概率最高的“nice”&#xf…

2023-8-15 差分

题目链接&#xff1a;差分 #include <iostream>using namespace std;const int N 100010;int n, m; int a[N], b[N];void insert(int l, int r, int c) {b[l] c;b[r 1] - c; }int main() {scanf("%d%d", &n, &m);for(int i 1; i < n; i)scanf…

“鸿蒙”商标被抢先注册,华为上诉失败,鸿蒙系统将被迫改名?

作为我国最著名的手机通讯企业之一&#xff0c;华为凭借着无与伦比的创新设计与可靠实用的用户体验&#xff0c;一度成为了国内最受欢迎的手机品牌。此外&#xff0c;华为手机在海外市场的销量也不遑多让&#xff0c;不仅质量优异&#xff0c;在通讯的稳定性与可靠性上&#xf…

韦东山老师 RTOS 入门课程(一)RTOS 介绍,熟悉裸机的汇编逻辑

韦东山老师 RTOS 入门课程 课程链接&#xff1a;韦东山直播公开课&#xff1a;RTOS实战项目之实现多任务系统 第1节&#xff1a;裸机程序框架和缺陷_哔哩哔哩_bilibili RTOS 介绍 裸机&#xff1a;固定顺序执行。 中断&#xff1a;可以一直专心做循环里的事情&#xff0c;直…

林【2017】

一、判断 二、单选 三、填空 四、应用 五、算法设计

C++笔记之左值与右值、右值引用

C笔记之左值与右值、右值引用 code review! 文章目录 C笔记之左值与右值、右值引用1.左值与右值2.右值引用——关于int&& r 10;3.右值引用——对比int&& r 10;和int& r 10;4.右值引用&#xff08;rvalue reference&#xff09;的概念 1.左值与右值 2.…