Author:孫東風
Date:04/08/2008
http://blog.csdn.net/dongfengsun/article/details/2262207
參考文獻:http://www.forum.nokia.com/document/Cpp_Developers_Library/GUID-96C272CA-2BED-4352-AE7C-E692B193EC06/html/Navigation_Pane_API4.html
⒈〖導航面板〗
導航面板由一個Navigation decorators、一個Navigation decorator controls集組成,Navigation decorator control可以是一個label、一個tab group或者一個volume control。導航面板裏的控件可以通過Navigation decorators來訪問。
這裏要說一下decorator這個詞的來歷,做過Java的程序員都知道,在Java裏有個decorator模式,也就是中文的 裝飾模式。
這個模式的產生是爲了在不改變一個類的代碼或不破壞一個類的接口的情況下爲該類添加功能,如下:
abtract class Origin{
abtract void OriginInterfOne();
abstract void OriginInterfTwo();
}
那麼如果想不改變Origin的代碼而又想爲該類添加功能就可以採用decorator模式,如下:
public class OriginDecorator implements Origin{
private Origin iOrigin;
public OriginDecorator(Origin aOrigin){
this.iOrigin = aOrigin;
}
public void OriginInterfOne(){
iOrigin.OriginInterfOne();
//Adding other functions.
}
public void OriginInterfTwo(){
iOrigin.OriginInterfTwo();
//Adding other functions.
}
}
那麼Nokia借用這個詞的用意就很容易知道了,Nokia是想提供這樣一個Decorator的接口,那麼Users可以在不改變接口的前提下輕鬆的爲Navigation pane添加Navigation decorator controls。
⒉〖訪問默認的導航面板控件〗
當使用導航面板的API時,第一步是通過調用CAknAppUi::StatusPane()得到應用程序的狀態面板指針。CAknAppUi是application UI的base class,我們知道在EIKON base application中大多數的Ui類都繼承自CAknViewAppUi類,而CAknViewAppUi就是繼承自CAknAppUi。
當通過CAknAppUi::StatusPane()得到應用程序的狀態面板指針後,導航面板就可以被訪問。
CAknNavigationControlContainer* iNaviPane;
狀態面板的layout是從AVKON資源裏讀取的,佈局資源也包含子面板裏面的控件信息。
//Gets a pointer to the status pane
CEikStatusPane* sp = StatusPane();
//Fetch pointer to the default navigation pane control
iNaviPane = (CAknNavigationControlContainer*)sp->Control(TUid::Uid(EEikStatusPaneUidNavi));
⒊〖從資源產生一個帶Label控件的導航面板〗
創建導航面板的第一步是定義狀態面板和Navigation pane decorator的資源。狀態面板的ID和type field值定義在avkon.hrh裏。Decorator的resource type被定義成ENaviDecoratorLabel因爲Decorator包含一個Label控件。
RESOURCE EIK_APP_INFO {
status_pane = r_app_status_pane;
}
RESOURCE STATUS_PANE_APP_MODEL r_app_status_pane {
panes=
{
SPANE_PANE
{
id = EEikStatusPaneUidNavi;
type = EAknCtNaviPane;
resource = r_navi_decorator;
}
};
}
RESOURCE NAVI_DECORATOR r_navi_decorator
{
type = ENaviDecoratorLabel;
control = NAVI_LABEL
{
txt="label";
};
}
⒋〖操作Decorator按鈕〗
導航面板按鈕在導航面板的兩端顯示爲箭頭形狀,每個按鈕的顯示可以獨立的控制。值得注意的是導航面板按鈕默認並不顯示出來,如果想顯示出來必須調用CAknNavigationDecorator::MakeScrollButtonVisible()函數,想把顯示出來的置爲不可以見就要調用CAknNavigationDecorator::SetScrollButtonDimmed()函數。
// Set the visibility of the buttons
iDecorator->MakeScrollButtonVisible( ETrue );
// Show the left arrow button
iDecorator->SetScrollButtonDimmed(CAknNavigationDecorator::ELeftButton, EFalse);
// Hide the right arrow button
iDecorator->SetScrollButtonDimmed(CAknNavigationDecorator::ERightButton, ETrue);
⒌〖監聽Decorator事件〗
Decorator能發送EAknNaviDecoratorEventRightTabArrow、EAknNaviDecoratorEventLeftTabArrow事件給監聽對象。爲了處理這兩個事件,Decorator的類必須繼承自MAknNaviDecoratorObserver並實現HandleNaviDecoratorEventL()方法,這個方法負責處理上述兩個事件。
In the example, CMyAppUi
observes the decorator events.
class CMyAppUi : public CAknViewAppUi, MAknNaviDecoratorObserver {
…
// From MAknNaviDecoratorObserver
void HandleNaviDecoratorEventL( TInt aEventID );
…
};
Register this object to decorator, so the object receives events. iDecorator
is a pointer to CAknNavigationDecorator
.
void CMyAppUi::Construct() {
…
// Access status pane
CEikStatusPane* sp = StatusPane();
// Get a pointer to navi pane
iNaviPane = (CAknNavigationControlContainer*)sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi));
// Get a pointer to the decorator created from resource
iDecorator = iNaviPane->ResourceDecorator();
// Register this object as an observer of decorator
iDecorator->SetNaviDecoratorObserver( this );
…
}
HandleNaviDecoratorEventL()
now can receive decorator events.
void CMyAppUi::HandleNaviDecoratorEventL( TInt aEventID ) {
if ( aEventID == EAknNaviDecoratorEventRightTabArrow )
{
// Do Event handling code here…
}
else if (aEventID == EAknNaviDecoratorEventRightTabArrow ) {
// Do Event handling code here…
}
}
⒍〖利用導航面板控件棧機制〗
爲了讓Decorators在導航面板上可見,decorator objects必須放到導航面板的控件棧上並且棧頂的對象顯示在導航面板上。
decorators在控件棧上可以進行Pushed、Replaced、Poped操作。如果控件棧裏已經有了某個decorator,那麼Pushed操作會把這個
decorator置於棧頂而顯示在導航面板上。
// Two different decorators are pushed to the control stack
// iDecorator2 will be shown on the navigation pane
iNaviPane->PushL( *iDecorator1 );
iNaviPane->PushL( *iDecorator2 );
// Pushing iDecorator1 again
// iDecorator1 will be shown on the navigation pane
iNaviPane->PushL( *iDecorator1 );
// Pop the topmost opject from the stack ( *iDecorator1 )
// iDecorator2 will be shown on the navigation pane
iNaviPane->Pop( iDecorator1 );
// Replace iDecorator2 with iDecorator3
// iDecorator3 will be shown on the navigation pane
iNaviPane->ReplaceL( *iDecorator2, *iDecorator3 );
{
type = ENaviDecoratorLabel;
control = NAVI_LABEL
{
txt="label_a";
};
}
導航面板decorator的資源標識被傳遞給函數CAknNavigationControlContainer::ConstructNavigationDecoratorFromResourceL()。
// Read the resource
iEikonEnv->CreateResourceReaderLC( reader, R_NAVI_DECORATOR_A );
// Construct the decorator from resource
iDecorator = iNaviPane->ConstructNavigationDecoratorFromResourceL( reader );
// Destroy the object that was put on CleanupStack by
// CreateResourceReaderLC()
CleanupStack::PopAndDestroy();
iNaviLabel = new( ELeave ) CAknNaviLabel;
// Set label type and label text
iNaviLabel->SetNaviLabelType( CAknNaviLabel:: ENavigationLabel);
iNaviLabel->SetTextL( _L( "label" ) );
// Create the decorator object with the label
iDecorator = CAknNavigationDecorator::NewL( iNaviPane, iNaviLabel, CAknNavigationDecorator::ENaviLabel );
iDecorator = iNaviPane->ResourceDecorator();
iDecorator = iNaviPane->ResourceDecorator();
// Getting the control from the decorator object
iNaviLabel = ( CAknNaviLabel* )iDecorator->DecoratedControl();
// Change text
iNaviLabel->SetTextL( _L( "new label" ) );
// Label text as info message
CEikonEnv::Static()->InfoMsg( *iNaviLabel->Text() );
實際上通過下面的方法可以簡單的創建一個帶Lable的decorator:
// Create the decorator and the label control
iDecorator = iNaviPane->CreateNavigationLabelL( _L("label") );