最近看一些程序中有多视图设置列表,学习了一下怎么实现的,简单记录一下,以免以后备查,主要功能如下图
程序主界面
选择菜单里的设置选项
打开设置视图一
打开设置视图二
1、UI类继承自MAknTabObserver类,并且实现它的void TabChangedL(TInt aIndex);函数(详细实现见下)。
2、在UI类里定义导航指示器的指针
CAknNavigationDecorator* iNaviDecorator;
3、在UI函数里进行如下实现
void CS60UIExampleAppUi::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EEikCmdExit:
case EAknSoftkeyExit:
Exit();
break;
//选择设置菜单
case ES60UIExampleSettings:
{
TUid naviPaneUid;
naviPaneUid.iUid = EEikStatusPaneUidNavi;
CEikStatusPane* statusPane = StatusPane();
CEikStatusPaneBase::TPaneCapabilities subPane =
statusPane->PaneCapabilities(naviPaneUid);
// if we can access the navigation pane
if (subPane.IsPresent() && subPane.IsAppOwned())
{
CAknNavigationControlContainer* naviPane =
(CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);
delete iNaviDecorator;
iNaviDecorator = NULL;
// ownership is transferred to us here
iNaviDecorator = naviPane->CreateTabGroupL();
// ownership not transferred
CAknTabGroup* tabGroup = (CAknTabGroup*) iNaviDecorator->DecoratedControl();
// Display two tabs of normal length on the navigation pane at a time
tabGroup->SetTabFixedWidthL(KTabWidthWithOneTab);//设置视图栏是显示一个标签还是多个
tabGroup->SetObserver(this);
//添加两个要显示的视图以及标题标题 ,也可以添加多个
HBufC* tab1Text = StringLoader::LoadLC(R_S60UIEXAMPLE_HIGHSCORE_TITLE_TEXT);
tabGroup->AddTabL(ES60UIExampleSettingsViewId1, *tab1Text);
CleanupStack::PopAndDestroy(tab1Text);
HBufC* tab2Text = StringLoader::LoadLC(R_S60UIEXAMPLE_RESETTING_TEXT);
tabGroup->AddTabL(ES60UIExampleSettingsViewId2, *tab2Text);
CleanupStack::PopAndDestroy(tab2Text);
// highlight the first tab
tabGroup->SetActiveTabByIndex(0);
naviPane->PushL(*iNaviDecorator);
//激活第一个视图
ActivateLocalViewL(TUid::Uid(tabGroup->TabIdFromIndex(0)));
}
break;
}
//当设置视图返回时,销毁导航栏
case ES60UIExampleDelNavi:
{
TUid naviPaneUid;
naviPaneUid.iUid = EEikStatusPaneUidNavi;
CEikStatusPane* statusPane = StatusPane();
CEikStatusPaneBase::TPaneCapabilities subPane =
statusPane->PaneCapabilities(naviPaneUid);
// if we can access the navigation pane
if (subPane.IsPresent() && subPane.IsAppOwned())
{
CAknNavigationControlContainer* naviPane =
(CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);
delete iNaviDecorator;
iNaviDecorator = NULL;
naviPane->PushDefaultL();
}
break;
}
default:
Panic(ES60UIExampleBasicUi);
break;
}
}
//导航栏接受按钮的响应
TKeyResponse CS60UIExampleAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
if (iNaviDecorator == NULL)
{
return EKeyWasNotConsumed;
}
CAknTabGroup* tabGroup = (CAknTabGroup*) iNaviDecorator->DecoratedControl();
if (tabGroup == NULL)
{
return EKeyWasNotConsumed;
}
// if we've got a tab group, then offer the key event to it.
return tabGroup->OfferKeyEventL(aKeyEvent, aType);
}
//根据按键显示不同的视图
void CS60UIExampleAppUi::TabChangedL(TInt aIndex)
{
if (iNaviDecorator != NULL)
{
CAknTabGroup* tabGroup = (CAknTabGroup*) iNaviDecorator->DecoratedControl();
ActivateLocalViewL(TUid::Uid(tabGroup->TabIdFromIndex(aIndex)));
}
}
//UI类的析构函数中删除相应的导航栏指示器
CS60UIExampleAppUi::~CS60UIExampleAppUi()
{
delete iNaviDecorator;
iNaviDecorator=NULL;
}
4、在继续自CAknSettingItemList的设置列表类里实现OfferKeyEventL函数,以避免左右导航失效
TKeyResponse CS60UIExampleList::OfferKeyEventL( const TKeyEvent & aKeyEvent,TEventCode aType)
{
if ( aType != EEventKey ) // Is not key event?
{
return EKeyWasNotConsumed;
}
switch(aKeyEvent.iCode)
{
case EKeyLeftArrow:
case EKeyRightArrow:
return EKeyWasNotConsumed;
break;
default:
break;
}
}
5、每一个设置列表的VIEW类里按返回按键时销毁UI里创建的导航指示器
void CS60UIExampleSettingsView::HandleCommandL (TInt aCommand)
函数里添加以下代码:
case EAknSoftkeyBack:
{
AppUi()->HandleCommandL(ES60UIExampleDelNavi);
AppUi()->ActivateLocalViewL (TUid::Uid (ES60UIExampleInitialViewId));
break;
}