blackberry自定義管理Screen棧

blackberry的screen類似於android平臺的activity,都是用來作爲UI顯示的容器,並且blackberry也提供類似於androidManager來自我管理ui的棧,但不足的是,blackberry的screen沒有生命週期的概念,於是作者試圖借鑑android對activity的管理方式來管理blackberry的screen棧。

基本思路是這樣的,我應用中的screen設計一個父類,裏面抽象出screen的四種狀態(生命週期)

/**
 * FileName: Screen.java
 * @Description: TODO(用一句話描述該文件做什麼)
 * All rights Reserved, Designed By 21winmess
 * Copyright: Copyright(C) 2010-2011 
 * * @author: Matrix xu
 * @version V2.0
 * Createdate: 2012-7-11 下午5:26:50
 *
 * Modification History:
 * Date Author Version Discription
 * -----------------------------------------------------------------------------------
 * 2012-7-11 Qute_Android2.0
 * Why & What is modified: <修改原因描述>
 */
import net.rim.device.api.ui.container.MainScreen;

/**
 * @ClassName: Screen
 * @Description:所有的頁面應實現這個抽象父類,提供生命週期回調函數
 * @author: Matrix
 * @date: 2012-7-11 下午5:26:50
 * 
 */
public abstract class BaseMainScreen extends MainScreen {

	private boolean isPause = false;

	private Intent intent;

	public BaseMainScreen() {
	}

	public BaseMainScreen(long style) {
		super(style);
	}

	/**
	 * @return the isPause
	 */
	public boolean isPause() {
		return isPause;
	}

	/**
	 * @param isPause
	 *            the isPause to set
	 */
	public void setPause(boolean isPause) {
		this.isPause = isPause;
	}

	/**
	 * @return the intent
	 */
	public Intent getIntent() {
		if (this.intent == null) {
			intent = new Intent();
		}
		return intent;
	}

	/**
	 * @param intent
	 *            the intent to set
	 */
	public void setIntent(Intent intent) {
		this.intent = intent;
	}

	/**
	 * When screen is created on fisrt time,FromFactory will invoke this
	 * method,so you can init the screen instance and properties at this time.
	 */
	protected abstract void onCreate();

	/**
	 * When screen is visiable,the method is invoked,but this methord is only
	 * execute once...
	 */
	protected abstract void onShow();

	/**
	 * when the screen is not visable,but still be in screen stack.
	 */
	protected abstract void onPause();

	/**
	 * When screen is pop from stack, the method is invoked..
	 */
	protected abstract void onFinish();

	protected boolean onSavePrompt() {
		return true;
	}
}


解釋一下4個回調函數的含義:(如果熟悉android activity的生命週期那麼理解起來就很容易了)

1.onCreate() 創建該畫面的時刻被回調

2.onShow() 畫面被顯示的時候被回調(這裏面要配合 UiApplication.getUiApplication().pushScreen(screenInstance);)

3.onPause()該畫面被掛到後臺的時候被調用

4.onFinish()該畫面被回收的時候被調用(這裏要配合UiApplication.getUiApplication().popScreen(screenInstance);)

之後我又設計了一個管理screen的容器 ScreenFactory,代碼如下:

/**
 * FileName: ScreenManager.java
 * @Description: TODO(用一句話描述該文件做什麼)
 * All rights Reserved, Designed By 21winmess
 * Copyright: Copyright(C) 2010-2011 
 * @author: Matrix xu
 * @version V2.0
 * Createdate: 2012-7-11 下午6:12:09
 *
 * Modification History:
 * Date Author Version Discription
 * -----------------------------------------------------------------------------------
 * 2012-7-11 Qute_Android2.0
 * Why & What is modified: <修改原因描述>
 */
import java.util.Stack;

import net.rim.device.api.ui.UiApplication;

/**
 * @ClassName: ScreenManager
 * @Description:用於管理screen的實例
 * @author: Matrix
 * @date: 2012-7-11 下午6:12:09
 * 
 */
public class ScreenFactory {

	private static Stack screenStack = new Stack();

	/**
	 * get current screen be showing
	 * 
	 * @return
	 */
	public BaseMainScreen currentScreen() {
		BaseMainScreen screenInstance = null;
		if (!screenStack.empty()) {
			screenInstance = (BaseMainScreen) screenStack.lastElement();
		}
		return screenInstance;

	}

	/**
	 * pause a screen instance
	 * 
	 * @param screenInstance
	 */
	private void screenPause(BaseMainScreen screenInstance) {
		if (!screenInstance.isPause()) {
			screenInstance.setPause(true);
		}
		screenInstance.onPause();
	}

	/**
	 * show screen which you want
	 * 
	 * @param screenClass
	 * @param intent
	 */
	public void screenShow(Class screenClass, Intent intent) {
		BaseMainScreen currentScreen = this.currentScreen();// 先獲得當前棧頂的對象
		BaseMainScreen screenInstance = this.screenIsContained(screenClass);
		if (screenInstance != null) {
			screenStack.removeElement(screenInstance);// 先刪掉,然後再push到stack
			try {
				UiApplication.getUiApplication().popScreen(screenInstance);
			} catch (Exception e) {
			}

		} else {
			screenInstance = this.screenCreate(screenClass);
		}
		if (intent != null) {
			screenInstance.setIntent(intent);
		}
		if (screenInstance.isPause()) {
			screenInstance.setPause(false);
		}
		screenInstance.onShow();
		screenStack.push(screenInstance);
		if (currentScreen != null) {
			screenPause(currentScreen);// 停止之前棧頂的對象,應該是被壓入到棧的第二位
		}
		try {
			UiApplication.getUiApplication().pushScreen(screenInstance);
		} catch (Exception e) {
		}

	}

	/**
	 * finish or remove the screen
	 * 
	 * @param screenClass
	 */
	public void screenFinish(Class screenClass) {
		BaseMainScreen screenInstance = this.screenIsContained(screenClass);
		if (screenInstance == null)
			return;
		this.screenPause(screenInstance);
		screenInstance.onFinish();
		screenStack.removeElement(screenInstance);
		UiApplication.getUiApplication().popScreen(screenInstance);
	}

	/**
	 * check the screen is contained in screen stack
	 * 
	 * @param screenClass
	 * @return
	 */
	public BaseMainScreen screenIsContained(Class screenClass) {
		BaseMainScreen screenInstance = null;
		for (int i = 0; i < screenStack.size(); i++) {
			screenInstance = (BaseMainScreen) screenStack.elementAt(i);
			if (screenClass.isInstance(screenInstance)) {
				return screenInstance;
			}
		}
		return null;
	}

	/**
	 * create a new screen instance by its clazz
	 * 
	 * @param screenClass
	 * @return
	 */
	private BaseMainScreen screenCreate(Class screenClass) {
		BaseMainScreen newScreen = null;
		try {
			screenClass = Class.forName(screenClass.getName());
			newScreen = (BaseMainScreen) screenClass.newInstance();
			newScreen.onCreate();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return newScreen;
	}

	// ======================單例模式===========================//
	private static ScreenFactory mSingleInstance = null;
	private static Object mSyncObject = new Object();

	public static ScreenFactory getSingleInstance() {
		synchronized (mSyncObject) {
			if (mSingleInstance == null)
				mSingleInstance = new ScreenFactory();
		}
		return mSingleInstance;
	}

}


這個類主要完成的事情就是管理應用中的所有screen畫面,並在適當的時刻去回調父類screen的回調函數。

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章