这是我参与「第四届青训营」笔记创作的第 6 天
此篇笔记是 Android 基础 —— 几种简单控件(二)按钮触控
本篇笔记分为 2 部分
- 按钮控件 Button
- 点击事件 与 长按事件
二、几种简单控件
按钮控件 Button
除了文本视图之外,按钮 Button 也是一种基础控件。因为 Button 是由 TextView 派生而来,所以文本视图拥有的属性和方法,包括文本内容、文本大小、文本颜色等,按钮控件均能使用。不同的是,Button 拥有默认的按钮背景,而 TextView 默认无背景;
Button 的内部文本默认居中对齐,而 TextView 的内部文本默认靠左对齐。此外,按钮还要额外注意 textAllCaps 与 onClick 两个属性,分别介绍如下
1. textAllCaps属性
对于 TextView 来说, text 属性设置了什么文本,文本视图就显示什么文本。但对于 Button 来说,不管 text 属性设置的是大写字母还是小写字母,按钮控件都默认转成大写字母显示。
比如在 XML 文件中加入下面的 Button 标签:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello,World!"/>
编译运行后的 App 界面,按钮上显示全大写的 “HELLO WORLD” ,而非原来大小写混合的 “Hello World” 。显然这个效果不符合预期,为此需要给 Button 标签补充 textAllCaps 属性,该属性默认为 true 表示全部转为大写,如果设置为 false 则表示不转为大写。于是在布局文件添加新的 Button 标签,该标签补充了 android:textAllCaps="false" ,具体内容如下所示:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello,World!"
android:textAllCaps="false"/>
再次运行 App ,此时包含新旧按钮的界面如图所示,可见 textAllCaps 属性果然能够控制大小写转换。
2. onClick属性
按钮之所以成为按钮,是因为它会响应按下动作,就手机而言,按下动作等同于点击操作,即手指轻触屏幕然后马上松开。每当点击按钮之时,就表示用户确认了某个事项,接下来轮到 App 接着处理了。
onClick 属性便用来接管用户的点击动作,该属性的值是个方法名,也就是当前页面的 Java 代码存在这么 一个方法:当用户点击按钮时,就自动调用该方法。 譬如下面的 Button 标签指定了 onClick 属性值为 doClick ,表示点击该按钮会触发 Java 代码中的 doClick 方法:
<Button
android:id="@+id/btn_click_xml"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="直接指定点击方法"
android:textColor="#000000"
android:textSize="17sp" />
与之相对应,页面所在的 Java 代码需要增加 doClick 方法,方法代码示例如下:
// activity_button_style.xml中给btn_click_xml指定了点击方法doClick
public void doClick(View view) {
String desc = String.format("%s 您点击了按钮:%s",
DateUtil.getNowTime(), ((Button) view).getText());
tv_result.setText(desc); // 设置文本视图的文本内容 }
然后编译运行,并在App界面上点击新加的按钮,点击前后的界面如图
点击事件 与 长按事件
虽然按钮控件能够在 XML 文件中通过 onClick 属性指定点击方法,但是方法的名称可以随便叫,既能叫 doClick 也能叫 doTouch ,甚至叫它 doA 或 doB 都没问题,这样很不利于规范化代码,倘若以后换了别人接手,就不晓得 doA 或 doB 是干什么用的。
因此在实际开发中,不推荐使用 Button 标签的 onClick 属性,而是在代码中给按钮对象注册点击监听器。
所谓监听器,意思是专门监听控件的动作行为,它平时无所事事,只有控件发生了指定的动作,监听器才会触发开关去执行对应的代码逻辑。点击监听器需要实现接口 View.OnClickListener ,并重写 onClick 方法补充点击事件的处理代码,再由按钮调用 setOnClickListener 方法设置监听器对象。
比如下面的代码给按钮控件 btn_click_single 设置了一个点击监听器:
// 从布局文件中获取名为btn_click_single的按钮控件
Button btn_click_single = findViewById(R.id.btn_click_single);
// 给btn_click_single设置点击监听器,一旦用户点击按钮,就触发监听器的onClick方法
btn_click_single.setOnClickListener(new MyOnClickListener());
上面的点击监听器名为 MyOnClickListener ,它的定义代码示例如下:
// 定义一个点击监听器,它实现了接口View.OnClickListener
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) { // 点击事件的处理方法
String desc = String.format("%s 您点击了按钮:%s",
DateUtil.getNowTime(), ((Button) v).getText());
tv_result.setText(desc); // 设置文本视图的文本内容
}
}
接着运行App,点击按钮之后的界面如图所示,可见点击动作的确触发了监听器的onClick方法。
如果一个页面只有一个按钮,单独定义新的监听器倒也无妨,可是如果存在许多按钮,每个按钮都定义自己的监听器,那就劳民伤财了。
对于同时监听多个按钮的情况,更好的办法是注册统一的监听器,也就是让当前页面实现接口 View.OnClickListener ,如此一来,onClick 方法便写在了页面代码之内。因为是统一的监听器,所以 onClick 内部需要判断是哪个按钮被点击了,也就是利用视图对象的 getId 方法检 查控件编号,完整的 onClick 代码举例如下:
@Override
public void onClick(View v) { // 点击事件的处理方法
if (v.getId() == R.id.btn_click_public) { // 来自于按钮btn_click_public
String desc = String.format("%s 您点击了按钮:%s",
DateUtil.getNowTime(), ((Button) v).getText());
tv_result.setText(desc); // 设置文本视图的文本内容
}
}
当然该页面的 onCreate 内部别忘了调用按钮对象的 setOnClickListener 方法,把按钮的点击监听器设置成当前页面,设置代码如下所示:
// 从布局文件中获取名为btn_click_public的按钮控件
Button btn_click_public = findViewById(R.id.btn_click_public);
// 设置点击监听器,一旦用户点击按钮,就触发监听器的onClick方法
btn_click_public.setOnClickListener(this);
重新运行App,点击第二个按钮之后的界面如图所示,可见当前页面的onClick方法也正确执行了。
除了点击事件,Android 还设计了另外一种长按事件,每当控件被按住超过 500 毫秒之后,就会触发该控件的长按事件。
若要捕捉按钮的长按事件,可调用按钮对象的 setOnLongClickListener 方法设置长按监听器。具体的设置代码示例如下:
// 从布局文件中获取名为btn_click_public的按钮控件
Button btn_longclick_public = findViewById(R.id.btn_longclick_public);
// 设置长按监听器,一旦用户长按按钮,就触发监听器的onLongClick方法
btn_longclick_public.setOnLongClickListener(this);
以上代码把长按监听器设置到当前页面,意味着该页面需要实现对应的长按接口 View.OnLongClickListener ,并重写长按方法 onLongClick ,下面便是重写后的 onLongClick 代码例子:
@Override
public boolean onLongClick(View v) { // 长按事件的处理方法
if (v.getId() == R.id.btn_longclick_public) { // 来自于按钮btn_longclick_public
String desc = String.format("%s 您长按了按钮:%s",
DateUtil.getNowTime(), ((Button) v).getText());
tv_result.setText(desc); // 设置文本视图的文本内容
}
return true;
}
再次运行 App,长按按钮之后的界面如图所示,说明长按事件果然触发了 onLongClick 方法。
值得注意的是,点击监听器和长按监听器不局限于按钮控件,其实它们都来源于视图基类 View,凡是从 View 派生而来的各类控件,均可注册点击监听器和长按监听器。
譬如文本视图 TextView ,其对象也能调用 setOnClickListener 方法与 setOnLongClickListene r方法,此时 TextView 控件就会响应点击动作和长按动作。
因为按钮存在按下和松开两种背景,便于提示用户该控件允许点击,但文本视图默认没有按压背景,不方便判断是否被点击,所以一般不会让文本视图处理点击事件和长按事件。