symbian的UI/引擎结构
*Symbian应用程序可以分为:
- UI(视图)
·将应用程序的数据在屏幕上显示给用户
— 引擎(模型)
·处理应用程序数据
不同的应用程序结构
*传统SymbianOS
*基于对话框
*基于Avkon视图
传统结构框图
应用程序类
*第一个需要创建的对象
*必须重写:
- CreateDocumentL()创建文档对象
- AppDIIUid()返回应用程序的唯一ID(如UID3)
class CMyAppApp::public CAknApplication
{
private:
......来自基类的函数
CApaDocument* CreateDocumentL();
TUid AppDIIUid() const;
};
文档类
*通常将应用程序的数据存至文件或从文件载入数据
- 在许多应用程序中,该功能是不需要的
- 在S60中,该功能默认是无效的
*构造函数必须将应用程序对象的引用传给CAknDocument
*必须重写CreateAppUiL()来创建AppUi
class CMyAppDocument:public CAknDocument
{
public:
static CMyAppDocument* NewL(CEikApplication & aApp);
virtual ~CMyAppDocument();
private:
CMyAppDocument(CEikApplication& aApp);
void ConstructL();
CEikAppUi* CreateAppUiL();
};
应用程序UI类
*处理应用程序中的命令(针对菜单)和事件(针对按键)
- 重写基类中的虚函数
*创建和拥有Container对象
*二阶段构造不需要通过NewL()来完成
class CMyAppAppUi:public CAknAppUi
{
public:
void ConstructL();
~CMyAppAppUi();
CMyAppAppUi();
private:
void DynInitMenuPaneL(IInt aResourceId,CEikMenuPane* aMenuPane);……主要是菜单的动态显示:菜单的选项可以跟着程序的状态动态地地调整。
void HandleCommandL(TInt aCommand);
private:
CMyAppContainer* iAppContainer;
};
容器类
*创建和拥有控件或容器
*处理与命令和事件有关的绘图操作
- 重写基类中的虚函数
class CMyAppContainer:public CCoeControl
{
public:
static CMyAppContainer* NewL(const TRect& aRect);
~CMyAppContainer();
private:
CMyAppContainer();
void ConstructL(const TRect& aRect);
private:.....来自基类的函数
void SizeChanged();
TInt CountComponentControls() const;反回组件数目
void Draw(const TRect& aRect) const;
private:^成员变量
CEikLabel* iLabel1;
CEikLabel* iLabel2;
};
优点和不足
*优点
- 十分灵活地实现应用程序UI的创建
- 开发者可以创造和设计自己的UI结构
*缺点
- 没有系统提供的视图管理系统,不方便复杂的应用程序的实现
基于对话框的结构框图
基于对话框的结构
*使用对话框作为主要视图(一种特殊的容器)
*多页对话框可以代表多重视图
- AVKON提供了自动的状态空格标签操作
*优点
- 可以在资源文件中修改内容和版面,不需要重新编译C++代码
*缺点
- 嵌套对话框如果没有认真书写代码将占有大量的栈空间
Avkon视图结构
Avkon视图结构介绍
*视图代表应用程序的显示页面
- 应用程序将“视图”注册到视图服务器
- 应用程序根据事件响应来激活/去激活视图服务器中的视图
- 某个时刻,在运行着的程序中只能有一个视图处于激活状态
*允许应用程序发送和接收请求来显示数据的某个特殊视图
*该结构可以认为是一种消息传递系统
*通过UI进行的导航是基于正在进行的任务
优点
*视图的数据和功能压缩到视图对象,然后各个视图进行自己的激活/去激活操作
*该结构更加面向对象,更加适合需要修改的情况
*视图的外部服务器管理意味着应用程序要发起请求来切换其他应用程序的视图
- 使得共享某个功能的应用程序之间的依赖性增强
- 降低了单个应用程序的复杂性
- 使应用程序更加高效
缺点
*视图结构框架是有限制的
*并不能用于所有情况
*只适用于不将视图提供给外部应用程序使用,或可以处理外部程序中断的应用程序
Avkon视图中的AppUi类
CAknViewAppUi
*所有基于视图结构的应用程序都必须由该类继承
*创建和管理应用程序视图,由CAknAppUi继承而来
*将绘图和基于屏幕的交互操作交予视图
*负责视图之间的切换
AppUi类示例
*视图通过AknViewAppUi派生类的ConstructL()来创建
void CMyAppUi::ConstructL()
{
BaseConstrcutL();
CMyView1* view1 = CMyView1::NewLC();...创建视图1
AddView(view1);....将所有权转移给CMyAppUi
CleanupStack::Pop();
CMyView2* view2 = CMyView2::NewLC();
AddViewL(view2);
CleanupStack::Pop();
...设置默认视图为视图1
ActivateLocalViewL(view1->Id())
}
Avkon视图类
CAknView
*处理视图中的命令和事件
*每个视图都相当于一个小的应用程序UI
*创建它自己的控件类,从CCoeContorl继承而来
Avkon视图类示例
*CAknView-派生类定义:
class CMyView1:public CAknView
{
public:...构造函数和析构函数
static CMyView1* NewL();
static CMyView1* NewLC();
virtual ~CMyView1();
public:..from CAknView
TUid Id() const ...返回视图id
void DoActivateL(const TVwsViewId& aPrevViewId,TUid aCustomMessageId, const TDesC8& aCustomMessage);
void DoActivete();
void HandleForegroundEventL(TBool aForeground);
void HandleCommandL(TInt aCommand);
void HandleStatusPaneSizeChange();
private:
CMyView1();...执行第一阶段构造函数
void ConstructL(); ....执行第二阶段构造函数
private:...成员变量
CMyContainer1 * iMyContainer1;....用于该视力的窗器
};
Avkon视图类函数
*构造
— NewL()和NewLC()进行二阶段构造
- 都调用私有的ConstructL()
调用CAknView::BaseConstructL()传递视图的资源ID
void CMyView1::ConstructL()
{
BaseConstructL(R_MY_VIEW_1);
}
*析构
- 完成和DoDeactivate()相同的功能
*Ui特有的构造/析构代码应位于DoActiveateL()和DoDeactive(),因为在一个时刻只有一个视图处于激活状态
*应该重写CAknView的
- Id()
@返回视图唯一ID,类型为TUid
@该ID由开发者在视图的头文件中定义
- DoAcitvateL(..)
@在激活视图时调用
@作为部分请求,可以接受消息参数
@创建视图的窗口并把它添加到栈中
@必须处理当视图已经处于激活状态时的调用
- DoDeactive()
@在去激活视图时调用(如退出应用程序或应用程序的其他视图被激活时)
@删除视力的容器并把它从应用程序UI栈中移去
@该函数绝对不可以忽略
- HandleForegroudEventL(TBool aForeground)
@用于设置焦点或控制屏幕更新
@只在视图处于激活状态时调用
@只在前景状态变化时调用
@aForeground取值
- ETrue当移至前景时
- EFalse当从前景移开时
-HandleCommandL()
@处理菜单/软键的命令
-HandaleStatusPaneSizeChange()
@当因为状态空格的改变导致客户端矩形尺寸发生变化时调用
Avkon视图资源
*每个视图都有相关联的资源,使得视图可以有自己的菜单和/或命令按钮数组(CBA)
*AVKON_VIEW资源提供
- 带有菜单的视图
- 带有CBA的视图
*示例
RESOURCE AVKON_VIEW r_my_view_1
{
menubar = r_my_menubar_1;
cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
}
切换视图
*由CAknViewAppUi根据用户命令的响应来处理
*本地视力切换
- 在同一个应用程序里激活其他的视图,去激活当前视图
- 通过指定目标视图的UID来实现
- CAknViewAppUi::ActivateLocalViewL(TUid aViewId)
*远程视图切换
- 激活其他应用程序的视图
- 通过指定目标应用程序的UID和目标视图的UID来实现
- CCoeAppUi::ActiveViewL(const TVwsView& aViewId)