Смена View в приложении с использованием CAknViewAppUi и CAknView

Цель данной статьи дать небольшое пояснение к ViewSwitchingCAknViewAppUi.zip,
далее называемый Пример. В примере показано как можно реализовать
переключение между различными View унаследованными от CCoeControl с
использованием CAknViewAppUi и CAknView.

Использование CAknViewAppUi и CAknView подразумевает, что архитектура вашего приложения будет являться примерно следующей:

 

CAknViewAppUi - UI контролер. В Примере это CTestAppUi. Его основные функции таковы:

  • Создание View контролеров, что наследуются от CAknView.
  • Обработка event'ов и команд меню, что не обрабатываются View контролерами.
  • Переключение между View'ами.

CAknView - View контролер. В Примере CTestViewMain, CTestViewAdd, CTestViewEdit:

  • Создание одного или несколько View.
  • Обработка event'ов и команд меню, им зарегистрированных.

View унаследованный от CCoeControl. В Примере CMainContainer, CAddContainer, CEditContainer:

  • собственно, он показывает данные приложения на экране.

Также
для корректной работы нам понадобится изменить основной rss файл нашего
приложения, Test.rss, и для удобства изменить Test.hrh.

Итак, обо всем по порядку.

1. Изменяем rss файл. Так как у нас теперь три View, то нам понадобится три AVKON_VIEW, по одному на каждый.

Вот так будет выглядеть описание меню для CTestViewMain.

//////////////Main View//////////////////
RESOURCE AVKON_VIEW r_test_view_main{
menubar = r_test_menubar_main;
cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
}
 
RESOURCE MENU_BAR r_test_menubar_main{
titles=
{
MENU_TITLE {menu_pane=r_test_menu_main;}
};
}
 
RESOURCE MENU_PANE r_test_menu_main{
items =
{
MENU_ITEM {
command=ETestMainAddCmd;
txt=qtn_command_main_add;
},
MENU_ITEM {
command=ETestMainEditCmd;
txt=qtn_command_main_edit;
},
MENU_ITEM {
command=EAknSoftkeyExit;
txt=qtn_exit;
}
};
}

Для остальных View контролеров создание меню происходит аналогично.

2. Создаем в Test.hrh файле enum, что будет содержать Id для каждого отдельного View.
По этим Id позже будет происходить переключение между View.

enum TTestViewId
{
EMainView = 0x7001,
EAddView,
EEditView
};

3. Создаем собственный UI контролер CTestAppUi : public CAknViewAppUi. Его особенностью будет метод ConstructL(),
в котором будут создаваться View контролеры:

void CTestAppUi::ConstructL(){

BaseConstructL();

CTestViewMain* view_main = new (ELeave) CTestViewMain;
view_main->ConstructL();
AddViewL( view_main );
iViewId1 = view_main->Id();
 
.............

SetDefaultViewL( *view_main );

}

4. Создаем View контролеры. Рассмотрим на примере CTestViewMain : public CAknView. Особенностями создания являются:

void CTestViewMain::ConstructL(){
// тот самый AVKON_VIEW, что мы определили в Test.rss
BaseConstructL(R_TEST_VIEW_MAIN);
}
 
TUid CTestViewMain::Id() const{
return TUid::Uid(EMainView);// тот самый Id, что мы определили в Test.hrh
}
 

void CTestViewMain::HandleCommandL(TInt aCommand){
switch( aCommand ){
case ETestMainAddCmd:
iEikonEnv->InfoMsg(R_TEST_MAIN_ADD);
// переключение в CTestViewAdd
AppUi()->ActivateLocalViewL(TUid::Uid(EAddView));
break;
case ETestMainEditCmd:
iEikonEnv->InfoMsg(R_TEST_MAIN_EDIT);
// переключение в CTestViewEdit
AppUi()->ActivateLocalViewL(TUid::Uid(EEditView));
break;
case EAknSoftkeyExit:
case EAknSoftkeyBack:
default:
// оставляем обработку незнакомых нам команд на совесть CTestAppUi
AppUi()->HandleCommandL(aCommand);
break;

}
}
/*
Здесь происходит переключение на один из View, подконтрольных данному View контролеру.
Но поскольку в моем примере каждый View контролер имеет только один View, то
параметры переключения(Id другого View и прочие) мне не нужны.
Здесь же сразу происходит создание требуемого View, если он еще не создан.
*/

void CTestViewMain::DoActivateL( const TVwsViewId& /*aPrevViewId*/,TUid /*aCustomMessageId*/,
const TDesC8& /*aCustomMessage*/){
if(!iContainer){
iContainer = CMainContainer::NewL( ClientRect() ) ;
iContainer->SetMopParent(this);
AppUi()->AddToStackL( *this, iContainer );
}

}

5. Создаем View. Тут ничего особенного, все также как и в
архитектуре с CAknAppUi. Также наследуем от CCoeControl и реализуем все
те же методы, что и в традиционной UI архитектуре.

6. Вроде все. Выложенное здесь приложение тестировалось лишь на WINSCW эмуляторе для S60 3rd Edition.
При написании активно использовалась C++ Developer's Library 1.4 и собственный код, основанный на коде пользователя A.A.M.


18.12.2009 Автор: Vogdb