用Java寫了這麼久的程序,一直沒有理解什麼是回調,在最近的Android開發工作中,一個偶然的需求讓我突然就對Java中的回調有了一個理解,遂記錄之。
首先這個需求是這樣的,一個Activity中的有一個View,我需要在不同的觸發條件下更換這個View的Layout,我們很容易想到寫一個方法,把要更換成的Layout的id傳進去,然後爲這個View設置一下content。就可以在不同的條件下調用這個函數來設置View的layout了,這不難理解。
但是,假設,現在該View的Layout更換成了LayoutA,LayoutA裏面有一個ImageView,我要對該ImageView通過代碼設置一些屬性;然後,另一時刻,該View的Layout換成了LayoutB,LayoutB裏面有一個Button,我要對該Button通過代碼做一些設置,怎麼辦?
我們可以這樣解決:
class MyActivity extends Activity {
View view;
int currentContentFlag;
private static final int ViewA = 1; // 標誌着當前View顯示的內容是ViewA
private static final int ViewB = 2; // 標誌着當前View顯示的內容是ViewB
/**
* 3.最後看這個函數
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 一些例如對view初始化工作略去
// 我們在這裏設置View的layout的Id爲layoutId_A
currentContentFlag = ViewA; // 修改當前顯示內容的flag,告訴這個setViewContent函數裏面到底執行setViewA還是setViewB
setViewContent(R.layout.layoutId_A);
}
/**
* 1.先看本函數
*/
private void setViewContent(int layoutId) {
view = LayoutInflater.from(this).inflate(layoutId, null); // 設置View的內容
switch (currentContentFlag) {
case ViewA:
// 說明當前View的內容是ViewA,在這裏用代碼對ViewA裏面的東西進行具體設置
setViewA(view);
break;
case ViewB:
// 說明當前View的內容是ViewB,在這裏用代碼對ViewB裏面的東西進行具體設置
setViewB(view);
break;
default :
break;
}
}
/**
* 2.再看這兩個函數
*/
private setViewA(View view) {
}
private setViewB(View view) {
}
}
這樣的話,每設置一次View的內容,都要修改當前顯示內容的flag,通過維護這個flag變量,來告訴這個setViewContent函數裏面到底執行setViewA還是setViewB。
這樣做可不可行呢?實現肯定也可以實現,但是,我想到了用回調機制來完成這件事。
什麼是回調呢?回調回調,回去調用。我理解回調,就是,在代碼執行的過程中,函數FunA()某一時刻被調用,那麼將轉去執行FunA(),在FunA執行的時候呢,又反過來去執行原代碼裏的一些東西。這應該是最淺顯的解釋了吧。
在Java語言裏面,我們可以通過interface實現自己的回調,Java裏面的interface真的太有用了。則上面的代碼可以改爲下面的實現:
class MyActivity extends Activity {
View view;
/**
* 3.看這個函數
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 一些例如對view初始化工作略去
// 我們在這裏設置View的layout的Id爲layoutId_A
currentContentFlag = ViewA;
setViewContent(R.layout.layoutId_A, new ConfigViewInterface() { // 傳進去一個接口,並覆蓋裏面的方法
public void setView(View view) {
setViewA(view);
}
});
}
/**
* 2.看本函數
*/
private void setViewContent(int layoutId, ConfigViewInterface configViewInterface) {
view = LayoutInflater.from(this).inflate(layoutId, null); // 設置View的內容
configViewInterface.setView(view);
}
/**
* 4.看這兩個函數
*/
private setViewA(View view) {
}
private setViewB(View view) {
}
/**
* 1.看本接口
*/
private interface ConfigViewInterface {
void setView(View view) ;
}
}
這樣是不是就好多了呢?慢慢理解下上面的代碼,多少會對你有幫助的。有時候學知識,就要所練,可能當時不理解某個點,不知什麼時候突然就懂了。
歡迎拍磚。