• Button's four click events


    第一种:内部类的方式

      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都会报异常。

    原因是什么呢?

    查看View源码得知:

    查看View源码里面的onClick属性:

    里面有一行 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这个名字,然后通过反射实现。

  • 相关阅读:
    给大家分享两款正在使用的reflector插件
    Win32汇编项目总结——猎杀潜航
    SQL Server2008 数据库误删除数据的恢复方法分享
    DataGridView中使DataGridViewComboBox可编辑
    将SQL数据库还原到某个时间点
    SQL Server 2005对海量数据处理
    SQL Server 2005对海量数据处理(1)
    ILDASM的使用
    QT简介以及配置
    Reflector插件介绍
  • 原文地址:https://www.cnblogs.com/lzp123456-/p/9653042.html
Copyright © 2020-2023  润新知