Author:孙东风
Date:04/08/2008
参考文献: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 );
// Label text as info message
CEikonEnv::Static()->InfoMsg( *iNaviLabel->Text() );
实际上通过下面的方法可以简单的创建一个带Lable的decorator:
// Create the decorator and the label controliDecorator = iNaviPane->CreateNavigationLabelL( _L("label") );