Android開發中Java回調機制的應用

  用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) ;
	}
}

  這樣是不是就好多了呢?慢慢理解下上面的代碼,多少會對你有幫助的。有時候學知識,就要所練,可能當時不理解某個點,不知什麼時候突然就懂了。

  歡迎拍磚。


發佈了52 篇原創文章 · 獲贊 63 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章