操作环境
Project:ButtonTest
IDE:Android Studio2.1
学习了几个月的Android,觉得有必要复习一下前面学过的知识,哪怕再简单的知识也是可以温故而知新的。就从最简单的按钮点击事件开始吧。我总结了五种不同的写法,如下:
- 匿名内部类
- 使用View.onClickListener
- 使用onClick属性
- 自定义单击事件监听类
- 使用外部类。
我在布局上按照不同的写法放置了五个按钮,点击不同的按钮,就会把按钮上的文字传递到顶部的TextView。下面是整体的UI界面:
这是我完成整个博客之后的界面,由于我是边写边运行边截图的,在下面你会看到按钮是一个一个加上去的。
1. 匿名内部类
这个写法用得非常多,只要调用setOnClickListener(),在里面传入匿名内部类就可以了使用接口中的onCLick方法了。
public class ButtonActivity extends AppCompatActivity {
private Button button1;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
textView = (TextView) findViewById(R.id.textView);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("匿名内部类");
}
});
}
}
完成效果:
2. 使用View.onClickListener 接口
我个人很喜欢这种写法,只要让Activity继承View.OnClickListener接口,然后让Button对象去调用setOnClickListener()方法,并在其中传入this就可以了。在点击事件特别多的时候,这种写法的优势就出来了:在OnClick方法中使用switch语句,就可以在不同控件的的点击事件中来回切换,非常的简洁和便利。
public class ButtonActivity extends AppCompatActivity implements View.OnClickListener{
private Button button1,button2;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
//初始化控件
textView = (TextView) findViewById(R.id.textView);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
//1.匿名内部类
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("匿名内部类");
}
});
//2.使用View.onClickListener接口
button2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
textView.setText("使用View.onClickListener接口");
}
}
3.使用onClick属性
这种写法简单到有点不可思议,它是五种方法中唯一没有在代码中继承View.onClickListener接口的,我们所要做的只是在xml文件中添加onClick属性:
android:onClick="buttonClick"
然后回到代码中写上下面的方法,方法名称就是你在OnClick属性中名字。
//3.使用onClick属性
public void buttonClick(View v){
textView.setText("使用onClick属性");
}
完成效果
如果你要设置的按钮点击事件只有那么一两个,这种写法无疑是非常省事的。但是如果你点击事件很多的话就要小心,因为不同按钮的点击事件是根据OnClick中的内容确定的,所以在xml文件中写太多的OnClick属性可能会弄混,到头来你都不记得哪一个方法对应哪一个按钮了。
那么有没有方法可以多个按钮都同时使用这种写法呢?答案是有的。你可以在多个Button的节点中使用OnClick属性,比如android:onClick=”buttonClick”,这时你点击这些按钮,调用的都是同一个buttonClick()方法。为了区分,这时候你就需要再给每一个按钮设置资源id,然后通过switch语句进行判断,写法如下。
public void buttonClick(View v){
int id = v.getId();
switch (id) {
case R.id.bt1:
System.out.println("按钮1");
break;
case R.id.bt2:
System.out.println("按钮2");
break;
case R.id.bt3:
System.out.println("按钮3");
break;
}
}
你可以自己设置多个按钮,然后打印不同的日志或者弹出不同的Toast来看看实现效果,这里我就不实现了。
4.自定义单击事件监听类
自定义其实就是创建一个类,然后去继承View.OnClickListener接口,然后去实现接口中的onClick()方法就可以了。
class MyClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
textView.setText("自定义单击事件监听类");
}
}
然后初始化Button按钮并调用setOnClickListener()方法,注意了,这里传进去的参数就是我们新建的类MyClickListener的匿名对象。
button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new MyClickListener());
这种写法应该比较冷门,反正我目前都没有使用过,毕竟要创建一个类看起来有点画蛇添足。
完成效果
5.使用外部类
第五种方法比较特别。它跟第四种很像,不同的是onClick()方法一共出现了两次。那么这有什么用呢?我们来试一下就知道了。新建一个外部类OuterClass,自然我们也让它继承View.OnClickListener接口,同时也让它打印一条log日志,以便我们查看它是否调用了:
//5.使用外部类
class OuterClassListener implements View.OnClickListener{
@Override
public void onClick(View v) {
Log.d("Tag", "父类中的onClick方法");
}
}
接下来的写法是不是有点眼熟?不错,跟匿名内部类一样,只不过这里的onClick方法编译器不会自动帮我们生成,需要我们自己动手添加。另外,要注意加上 super.onClick(v)这一句,表示调用父类中的onClick方法。
//5.使用外部类
button5 = (Button) findViewById(R.id.button5);
button5.setOnClickListener(new OuterClassListener(){
@Override
public void onClick(View v) {
super.onClick(v);
textView.setText("使用外部类");
}
});
完成效果:
运行之后,点击按钮,除了我们预期中的TextView的文字发生变化之后,还打印了一条log日志:
这说明点击按钮之后,父类和子类的onClick方法都调用了。那么,这样的写法有什么好处呢?这种写法的好处在于当子类较多时,我们可以把子类的相同代码集中到父类中,这样父类就可以批量实现你所需要的效果,避免了代码冗余。
完整代码
最后贴上完整的代码吧。本人还在学习中,所以如果有错误的话还请大家多多指正。
activity_button.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.lin.mr.buttontest.ButtonActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="接收传过来的文字"
android:textSize="25sp" />
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="匿名内部类" />
<Button
android:layout_marginTop="10dp"
android:id="@+id/button2"
android:text="使用View.OnClickListener接口"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:onClick="buttonClick"
android:layout_marginTop="10dp"
android:id="@+id/button3"
android:text="使用onClick属性"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_marginTop="10dp"
android:id="@+id/button4"
android:text="自定义单击事件监听类"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_marginTop="10dp"
android:id="@+id/button5"
android:text="使用外部类"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
ButtonActivity
package com.lin.mr.buttontest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class ButtonActivity extends AppCompatActivity implements View.OnClickListener{
private Button button1,button2,button4,button5;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
//初始化控件
textView = (TextView) findViewById(R.id.textView);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new MyClickListener());
//5.使用外部类
button5 = (Button) findViewById(R.id.button5);
button5.setOnClickListener(new OuterClassListener(){
@Override
public void onClick(View v) {
super.onClick(v);
textView.setText("使用外部类");
}
});
//1.匿名内部类
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("匿名内部类");
}
});
//2.使用View.onClickListener接口
button2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
textView.setText("使用View.onClickListener接口");
}
//3.使用onClick属性
public void buttonClick(View v){
textView.setText("使用onClick属性");
}
//4.自定义单击事件监听类
class MyClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
textView.setText("自定义单击事件监听类");
}
}
//5.使用外部类
class OuterClassListener implements View.OnClickListener{
@Override
public void onClick(View v) {
Log.d("Tag", "父类中的onClick方法");
}
}
}
补充知识:OnClick()方法中的参数
写了这么多种点击事件的写法之后,有没有发现onClick()方法中总是需要传入一个参数呢?这个参数是什么呢?乍一看,这应该是View的一个对象。我们在学习第3种写法(使用onClick属性)时提到了switch语句:
public void buttonClick(View v){
int id = v.getId();
switch (id) {
case R.id.bt1:
break;
case R.id.bt2:
break;
case R.id.bt3:
break;
}
}
注意到这一句:“int id = v.getId();”。v是View的对象,它通过getId()方法获取到了Button的Id,然后将获取到的id交给switch进行判断,从而实现不同按钮的点击事件。所以onClick()方法里面的参数就是触发点击方法执行的组件对象,在这里,我们的组件毫无疑问就是Button按钮了。

本文详细介绍了Android中Button点击事件的五种实现方式,包括匿名内部类、使用View.onClickListener接口、onClick属性、自定义单击事件监听类以及使用外部类。每种方法都有其适用场景和优缺点,例如匿名内部类常用且简洁,使用onClick属性方便但易混淆,自定义监听类适用于代码复用。文中还提到onClick方法参数的作用,帮助理解事件处理机制。
3328

被折叠的 条评论
为什么被折叠?



