第一種:內部類的方式 第二種:匿名內部類 第三種按鈕點擊事件:讓當前類實現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都會報異常。
原因是什麼呢?
查看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這個名字,然後通過反射實現。