深入探索Symbian导航面板开发

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的Decorator〗
RESOURCE NAVI_DECORATOR r_navi_decorator_a
{
type = ENaviDecoratorLabel;
control = NAVI_LABEL
{
txt="label_a";
};
}
导航面板decorator的资源标识被传递给函数CAknNavigationControlContainer::ConstructNavigationDecoratorFromResourceL()。
下面的例子里iDecorator 是一个CAknNavigationDecorator型指针,在资源文件里可以定义多个导航面板decorator,从而程序里面可以动态的从资源文件读取。导航面板decorators的可见性可以用导航面板控件栈来控制。
TResourceReader reader;

// 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();
当然也可以不通过资源文件,在程序里动态的创建导航面板decorators,如下:
// Create the label object
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 );
从资源文件创建的decorators可以通过下面的代码访问:
// Get the decorator constructed from resource
iDecorator = iNaviPane->ResourceDecorator();
那么改变decorators里控件的label可以通过如下方法:
// Get the decorator constructed from resource
iDecorator = iNaviPane->ResourceDecorator();
// Getting the control from the decorator object
iNaviLabel = ( CAknNaviLabel* )iDecorator->DecoratedControl();
// Change text
iNaviLabel->SetTextL( _L( "new label" ) );
而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") );

你可能感兴趣的:(UI,Access,Symbian,Nokia)