Button's four click events

来源:https://www.cnblogs.com/lzp123456-/archive/2018/09/15/9653042.html
-Advertisement-
Play Games

第一種:內部類的方式 第二種:匿名內部類 第三種按鈕點擊事件:讓當前類實現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這個名字,然後通過反射實現。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: 最好不要給資料庫留NULL,儘可能的使用 NOT NULL填充資料庫. 備註 ...
  • 目前大數據和人工智慧作為兩大熱門方向,不僅僅國家在政策上進行支持,同時國內以百度,阿裡為首的知名互聯網企業也正在積極的佈局大數據和人工智慧。 自 2015 年以來,中國的人工智慧政策密集出台,這也意味著,在全球競爭的背景下,人工智慧已經上升為國家意志。 而且最近首部高中AI教材發佈,標志著AI已經正 ...
  • 昨天一開發同事反饋一個存儲過程很慢,但是重編譯後,存儲過程就很快了。瞭解基本情況後,初步判斷是參數嗅探問題。那麼如何診斷定位、分析問題呢?下麵簡單介紹一下這次參數嗅探問題定位的流程過程。 首先查看該存儲過程的執行計劃相關信息: 如下截圖所示,此存儲過程是2018-09-12 9:03:01緩存的,最... ...
  • 使用閃回技術,實現基於磁碟上閃回恢復區的自動備份與還原。 一、恢復表對象 1.創建學生表 2.添加記錄 3.刪除表 4.資料庫回收站多一條新的記錄 二、找回表數據 1.按某條件刪除表記錄,例如 2.如果是刪了或修改裡面的數據,可以先建立一個快表將刪除修改之前狀態的數據找回到這個表中 3.QUICK_ ...
  • SQL語句沒寫好可能導致: 1)網速不給力,不穩定。 2)伺服器記憶體不夠,或者SQL 被分配的記憶體不夠。 3)sql語句設計不合理 4)沒有相應的索引,索引不合理 5)沒有有效的索引視圖 6)表數據過大沒有有效的分區設計 7)資料庫設計太2,存在大量的數據冗餘 8)索引列上缺少相應的統計信息,或者統 ...
  • 1、xcall.sh 批量命令腳本,例:xcall.sh jps ,查看hadoop101~ hadoop104的jps進程 2、xsync.sh 集群同步文件,分發文件腳本,例:xsync.sh /usr/loacl/test.sh,在hadoop101~hadoop104上的/usr/local ...
  • 一般使用dp,不使用px。sp啥時候用呢?給TextView設置文字大小的時候用。 ...
  • 線性佈局: 相對佈局: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...