欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Button's four click events

程序员文章站 2022-07-21 21:18:00
第一种:内部类的方式 第二种:匿名内部类 第三种按钮点击事件:让当前类实现onClickListener接口。 第四种按钮的点击事件: 如果将click方法中的View v去掉或者方法名不是click都会报异常。 原因是什么呢? 查看View源码得知: 查看View源码里面的onClick属性: 里 ......

第一种:内部类的方式

  1 package com.example.phonedialer;
  2 
  3 import com.example.click2.r;
  4 
  5 import android.net.uri;
  6 import android.os.bundle;
  7 import android.app.activity;
  8 import android.content.intent;
  9 import android.view.menu;
 10 import android.view.view;
 11 import android.view.view.onclicklistener;
 12 import android.widget.button;
 13 import android.widget.edittext;
 14 import android.widget.toast;
 15 
 16 public class mainactivity extends activity {
 17 
 18     private edittext et_number;
 19 
 20 
 21     @override
 22     protected void oncreate(bundle savedinstancestate) {
 23         super.oncreate(savedinstancestate);
 24         //加载一个布局
 25         setcontentview(r.layout.activity_main);
 26         //找到我们关心的控件;通过源码得知edittext继承textview,textview继承自view,所以可以这样写。
 27         et_number = (edittext) findviewbyid(r.id.edittext1);
 28         
 29         //找到按钮;通过源码得知button继承自textview,textview继承自view,所以可以这样写。
 30         button btn_call = (button) findviewbyid(r.id.button1);
 31         /**
 32          * 方法里面接收的参数是onclicklistener类型,发现它是一个接口类型。
 33          * interface definition for a callback to be invoked when a view is clicked.
 34          * 定义了一个接口类型,注册了一个回调事件,当一个view被点击的时候走这个回调方法。
 35          */
 36         btn_call.setonclicklistener(new myclicklistener());
 37         /**
 38          * 这里的this(context也就是上下文的意思),代表mainactivity。查看源码可以得知
 39          * mainactivity继承自context.
 40          */
 41         //toast.maketext(this, text, duration)
 42         
 43     }
 44     /**
 45      * 定义一个类,去实现按钮需要的接口类型
 46      */
 47     private class myclicklistener implements onclicklistener {
 48 
 49         /**
 50          * called when a view has been clicked.
 51          * 当按钮已经被点击的时候调用该方法。
 52          */
 53         @override
 54         public void onclick(view v) {
 55             /**
 56              * 获取edittext控件的文本内容,第一时间想到通过et_number来获取,
 57              * 但是这个变量不是全局变量,获取不到。所以需要将它变成全局变量。
 58              * return the text the textview is displaying
 59              * 返回textview显示的内容。
 60              * editable android.widget.edittext.gettext()
 61              */
 62             string number = et_number.gettext().tostring().trim();
 63             if("".equals(number)) {
 64                 /**
 65                  * context上下文
 66                  * the method maketext(context, charsequence, int) 
 67                  * in the type toast is not applicable for the arguments (mainactivity.myclicklistener, string, int)
 68                  * 这里的this代表的是mainactivity.myclicklistener,需要的是一个context,所以编译报错。
 69                  * 通过类名.this可以设置吐司要在哪个activity显示。length_short 0  length_long 1
 70                  */
 71                 toast.maketext(mainactivity.this, "number不能为空", toast.length_short).show(); 
 72                 return;
 73             }
 74             //拿到number进行拨打电话.
 75             /**
 76              * 因为拨打电话的代码谷歌工程师已经写好了,所以不需要我们手动写逻辑,我们只需要
 77              * 把它调起来就可以了。意图:intent
 78              */ 
 79             intent intent = new intent();
 80             //设置动作 打电话。
 81             intent.setaction(intent.action_call);
 82             //设置打的数据 uri数据。uri data
 83             /**
 84              * url:统一资源定位符 
 85              * uri:统一资源标识符 自己定义的路径想代表什么就代表什么。
 86              */
 87             intent.setdata(uri.parse("tel:"+number));
 88             //开启意图
 89             startactivity(intent); 
 90             
 91             
 92             
 93         }
 94         
 95     }
 96     
 97 
 98 
 99     @override
100     public boolean oncreateoptionsmenu(menu menu) {
101         // inflate the menu; this adds items to the action bar if it is present.
102         getmenuinflater().inflate(r.menu.main, menu);
103         return true;
104     }
105     
106 }

第二种:匿名内部类 

 

 1 package com.example.phonedialer;
 2 
 3 import com.example.click3.r;
 4 
 5 import android.net.uri;
 6 import android.os.bundle;
 7 import android.app.activity;
 8 import android.content.intent;
 9 import android.view.menu;
10 import android.view.view;
11 import android.view.view.onclicklistener;
12 import android.widget.button;
13 import android.widget.edittext;
14 import android.widget.toast;
15 
16 public class mainactivity extends activity {
17 
18     private edittext et_number;
19 
20 
21     @override
22     protected void oncreate(bundle savedinstancestate) {
23         super.oncreate(savedinstancestate);
24         //加载一个布局
25         setcontentview(r.layout.activity_main);
26         //找到我们关心的控件;通过源码得知edittext继承textview,textview继承自view,所以可以这样写。
27         et_number = (edittext) findviewbyid(r.id.edittext1);
28         
29         //找到按钮;通过源码得知button继承自textview,textview继承自view,所以可以这样写。
30         button btn_call = (button) findviewbyid(r.id.button1);
31         /**
32          * 方法里面接收的参数是onclicklistener类型,发现它是一个接口类型。
33          * interface definition for a callback to be invoked when a view is clicked.
34          * 定义了一个接口类型,注册了一个回调事件,当一个view被点击的时候走这个回调方法。
35          */
36 //        btn_call.setonclicklistener(new myclicklistener());
37         btn_call.setonclicklistener(new onclicklistener() {
38             
39             @override
40             public void onclick(view v) {
41                 // todo auto-generated method stub
42                 /**
43                  * 获取edittext控件的文本内容,第一时间想到通过et_number来获取,
44                  * 但是这个变量不是全局变量,获取不到。所以需要将它变成全局变量。
45                  * return the text the textview is displaying
46                  * 返回textview显示的内容。
47                  * editable android.widget.edittext.gettext()
48                  */
49                 string number = et_number.gettext().tostring().trim();
50                 if("".equals(number)) {
51                     /**
52                      * context上下文
53                      * the method maketext(context, charsequence, int) 
54                      * in the type toast is not applicable for the arguments (mainactivity.myclicklistener, string, int)
55                      * 这里的this代表的是mainactivity.myclicklistener,需要的是一个context,所以编译报错。
56                      * 通过类名.this可以设置吐司要在哪个activity显示。length_short 0  length_long 1
57                      */
58                     toast.maketext(mainactivity.this, "number不能为空", toast.length_short).show(); 
59                     return;
60                 }
61                 //拿到number进行拨打电话.
62                 /**
63                  * 因为拨打电话的代码谷歌工程师已经写好了,所以不需要我们手动写逻辑,我们只需要
64                  * 把它调起来就可以了。意图:intent
65                  */ 
66                 intent intent = new intent();
67                 //设置动作 打电话。
68                 intent.setaction(intent.action_call);
69                 //设置打的数据 uri数据。uri data
70                 /**
71                  * url:统一资源定位符 
72                  * uri:统一资源标识符 自己定义的路径想代表什么就代表什么。
73                  */
74                 intent.setdata(uri.parse("tel:"+number));
75                 //开启意图
76                 startactivity(intent); 
77             }
78         });
79         
80     }
81     
82 
83 
84     @override
85     public boolean oncreateoptionsmenu(menu menu) {
86         // inflate the menu; this adds items to the action bar if it is present.
87         getmenuinflater().inflate(r.menu.main, menu);
88         return true;
89     }
90     
91 }

 

第三种按钮点击事件:让当前类实现onclicklistener接口。

  1 package com.example.phonedialer;
  2 
  3 import com.example.click3.r;
  4 
  5 import android.net.uri;
  6 import android.os.bundle;
  7 import android.app.activity;
  8 import android.content.intent;
  9 import android.view.menu;
 10 import android.view.view;
 11 import android.view.view.onclicklistener;
 12 import android.widget.button;
 13 import android.widget.edittext;
 14 import android.widget.toast;
 15 
 16 public class mainactivity extends activity implements onclicklistener {
 17 
 18     private edittext et_number;
 19     private button btn_call;
 20     private button btn_call1;
 21     private button btn_call2;
 22     private button btn_call3;
 23 
 24     @override
 25     protected void oncreate(bundle savedinstancestate) {
 26         super.oncreate(savedinstancestate);
 27         // 加载一个布局
 28         setcontentview(r.layout.activity_main);
 29         // 找到我们关心的控件;通过源码得知edittext继承textview,textview继承自view,所以可以这样写。
 30         et_number = (edittext) findviewbyid(r.id.edittext1);
 31 
 32         btn_call = (button) findviewbyid(r.id.button1);
 33         btn_call1 = (button) findviewbyid(r.id.button2);
 34         btn_call2 = (button) findviewbyid(r.id.button3);
 35         btn_call3 = (button) findviewbyid(r.id.button4);
 36         /**
 37          * 方法里面接收的参数是onclicklistener类型,发现它是一个接口类型。 interface definition for a
 38          * callback to be invoked when a view is clicked.
 39          * 定义了一个接口类型,注册了一个回调事件,当一个view被点击的时候走这个回调方法。
 40          */
 41         // btn_call.setonclicklistener(new myclicklistener());
 42         btn_call.setonclicklistener(this);
 43         btn_call1.setonclicklistener(this);
 44         btn_call2.setonclicklistener(this);
 45         btn_call3.setonclicklistener(this);
 46 
 47     }
 48 
 49     @override
 50     public boolean oncreateoptionsmenu(menu menu) {
 51         // inflate the menu; this adds items to the action bar if it is present.
 52         getmenuinflater().inflate(r.menu.main, menu);
 53         return true;
 54     }
 55 
 56     @override
 57     public void onclick(view v) {
 58         // 具体判断点击的是哪个按钮
 59         switch (v.getid()) {
 60         case r.id.button1:
 61             callphone(btn_call);
 62             break;
 63         case r.id.button2:
 64             callphone(btn_call1);
 65             break;
 66         case r.id.button3:
 67             callphone(btn_call2);
 68             break;
 69         case r.id.button4:
 70             callphone(btn_call3);
 71             break;
 72 
 73         default:
 74             break;
 75         }
 76     }
 77 
 78     private void callphone(button btn_call) {
 79         btn_call.setonclicklistener(new onclicklistener() {
 80 
 81             @override
 82             public void onclick(view v) {
 83                 // todo auto-generated method stub
 84                 /**
 85                  * 获取edittext控件的文本内容,第一时间想到通过et_number来获取,
 86                  * 但是这个变量不是全局变量,获取不到。所以需要将它变成全局变量。 return the text the textview
 87                  * is displaying 返回textview显示的内容。 editable
 88                  * android.widget.edittext.gettext()
 89                  */
 90                 string number = et_number.gettext().tostring().trim();
 91                 if ("".equals(number)) {
 92                     /**
 93                      * context上下文 the method maketext(context, charsequence,
 94                      * int) in the type toast is not applicable for the
 95                      * arguments (mainactivity.myclicklistener, string, int)
 96                      * 这里的this代表的是mainactivity
 97                      * .myclicklistener,需要的是一个context,所以编译报错。
 98                      * 通过类名.this可以设置吐司要在哪个activity显示。length_short 0 length_long
 99                      * 1
100                      */
101                     toast.maketext(mainactivity.this, "number不能为空",
102                             toast.length_short).show();
103                     return;
104                 }
105                 // 拿到number进行拨打电话.
106                 /**
107                  * 因为拨打电话的代码谷歌工程师已经写好了,所以不需要我们手动写逻辑,我们只需要 把它调起来就可以了。意图:intent
108                  */
109                 intent intent = new intent();
110                 // 设置动作 打电话。
111                 intent.setaction(intent.action_call);
112                 // 设置打的数据 uri数据。uri data
113                 /**
114                  * url:统一资源定位符 uri:统一资源标识符 自己定义的路径想代表什么就代表什么。
115                  */
116                 intent.setdata(uri.parse("tel:" + number));
117                 // 开启意图
118                 startactivity(intent);
119             }
120         });
121 
122     }
123 }

第四种按钮的点击事件:

  1 package com.example.phonedialer;
  2 
  3 import com.example.click4.r;
  4 
  5 import android.net.uri;
  6 import android.os.bundle;
  7 import android.app.activity;
  8 import android.content.intent;
  9 import android.view.menu;
 10 import android.view.view;
 11 import android.view.view.onclicklistener;
 12 import android.widget.button;
 13 import android.widget.edittext;
 14 import android.widget.toast;
 15 
 16 public class mainactivity extends activity implements onclicklistener {
 17 
 18     private edittext et_number;
 19     private button btn_call;
 20     private button btn_call1;
 21     private button btn_call2;
 22     private button btn_call3;
 23     private button btn_call4;
 24 
 25     @override
 26     protected void oncreate(bundle savedinstancestate) {
 27         super.oncreate(savedinstancestate);
 28         // 加载一个布局
 29         setcontentview(r.layout.activity_main);
 30         // 找到我们关心的控件;通过源码得知edittext继承textview,textview继承自view,所以可以这样写。
 31         et_number = (edittext) findviewbyid(r.id.edittext1);
 32 
 33         btn_call = (button) findviewbyid(r.id.button1);
 34         btn_call1 = (button) findviewbyid(r.id.button2);
 35         btn_call2 = (button) findviewbyid(r.id.button3);
 36         btn_call3 = (button) findviewbyid(r.id.button4);
 37         btn_call4 = (button) findviewbyid(r.id.button5);
 38         /**
 39          * 方法里面接收的参数是onclicklistener类型,发现它是一个接口类型。 interface definition for a
 40          * callback to be invoked when a view is clicked.
 41          * 定义了一个接口类型,注册了一个回调事件,当一个view被点击的时候走这个回调方法。
 42          */
 43         // btn_call.setonclicklistener(new myclicklistener());
 44         btn_call.setonclicklistener(this);
 45         btn_call1.setonclicklistener(this);
 46         btn_call2.setonclicklistener(this);
 47         btn_call3.setonclicklistener(this);
 48 
 49     }
 50     
 51     public void click(view v) {
 52         
 53         callphone(btn_call4);
 54     }
 55 
 56     @override
 57     public boolean oncreateoptionsmenu(menu menu) {
 58         // inflate the menu; this adds items to the action bar if it is present.
 59         getmenuinflater().inflate(r.menu.main, menu);
 60         return true;
 61     }
 62 
 63     @override
 64     public void onclick(view v) {
 65         // 具体判断点击的是哪个按钮
 66         switch (v.getid()) {
 67         case r.id.button1:
 68             callphone(btn_call);
 69             break;
 70         case r.id.button2:
 71             callphone(btn_call1);
 72             break;
 73         case r.id.button3:
 74             callphone(btn_call2);
 75             break;
 76         case r.id.button4:
 77             callphone(btn_call3);
 78             break;
 79 
 80         default:
 81             break;
 82         }
 83     }
 84 
 85     private void callphone(button btn_call) {
 86         btn_call.setonclicklistener(new onclicklistener() {
 87 
 88             @override
 89             public void onclick(view v) {
 90                 // todo auto-generated method stub
 91                 /**
 92                  * 获取edittext控件的文本内容,第一时间想到通过et_number来获取,
 93                  * 但是这个变量不是全局变量,获取不到。所以需要将它变成全局变量。 return the text the textview
 94                  * is displaying 返回textview显示的内容。 editable
 95                  * android.widget.edittext.gettext()
 96                  */
 97                 string number = et_number.gettext().tostring().trim();
 98                 if ("".equals(number)) {
 99                     /**
100                      * context上下文 the method maketext(context, charsequence,
101                      * int) in the type toast is not applicable for the
102                      * arguments (mainactivity.myclicklistener, string, int)
103                      * 这里的this代表的是mainactivity
104                      * .myclicklistener,需要的是一个context,所以编译报错。
105                      * 通过类名.this可以设置吐司要在哪个activity显示。length_short 0 length_long
106                      * 1
107                      */
108                     toast.maketext(mainactivity.this, "number不能为空",
109                             toast.length_short).show();
110                     return;
111                 }
112                 // 拿到number进行拨打电话.
113                 /**
114                  * 因为拨打电话的代码谷歌工程师已经写好了,所以不需要我们手动写逻辑,我们只需要 把它调起来就可以了。意图:intent
115                  */
116                 intent intent = new intent();
117                 // 设置动作 打电话。
118                 intent.setaction(intent.action_call);
119                 // 设置打的数据 uri数据。uri data
120                 /**
121                  * url:统一资源定位符 uri:统一资源标识符 自己定义的路径想代表什么就代表什么。
122                  */
123                 intent.setdata(uri.parse("tel:" + number));
124                 // 开启意图
125                 startactivity(intent);
126             }
127         });
128 
129     }
130 }

如果将click方法中的view v去掉或者方法名不是click都会报异常。

Button's four click events

原因是什么呢?

查看view源码得知:

查看view源码里面的onclick属性:

Button's four click events

里面有一行 1 mhandler = getcontext().getclass().getmethod(handlername, 2 view.class); 这样的代码,拿到一个上下文对象的字节码文件(反射)。其中handlername是onclick属性的名字click,而view.class是该方法需要传入的参数。

handlername是怎么来的呢?

 1 final string handlername = a.getstring(attr);是通过a拿到的。handlername其实就是click。

a是什么呢?

1  public view(context context, attributeset attrs, int defstyle) {
2         this(context);
3 
4         typedarray a = context.obtainstyledattributes(attrs, com.android.internal.r.styleable.view,
5                 defstyle, 0);

从这段代码可以得知,通过attrs这个对象就找到了click这个名字,然后通过反射实现。