S60视图(View)结构简介
在S60平台的应用程序开发中,视图架构(View architecture)是一种被广泛应用的技术。一个图形用户界面(GUI)应用程序可以创建若干个视图,每个视图用来显示不同的应用程序数据或者用户界面的控件。每一个视图,都拥有自己的控件栈(Stack)。每个视图的容器(container,一种用以集合子控件父控件)和控件都是在视图被启动时候才被创建的,而当同一个应用程序的其他视图被启动的时候,当前视图的控件和容器会被删除。当一个视图被启动的时候,将会有一个消息ID参数以及一个消息参数传递给要被激活的视图。这个机制就大大增加了应用程序的功能可重用性,你可以使用其它已存在的应用程序的某个视图来为你的程序增添功能。
视图架构的概览
在传统Eikon图形界面应用程序中的AppUi类里,你可以创建容器类(container class),用容器来作为子控件的管理工具。在基于视图的图形界面应用程序中,我们可以创建继承自CAknView的视图类,该类对象是AppUi的成员变量,而AppUi则应是继承自CAknViewAppUi。CAknViewAppUi其实是CAknAppUi类的子类,他增添了一些处理视图的方法/函数。视图的被激活(Activation)和被移除(Deactivation)处理,是在视图类中由函数DoActivateL()和DoDeActivateL()来完成的,而不是在视图的管理类中进行的。在上述函数中,视图的容器类被构造或析构,而容器类负责对每一个子控件进行构造和析构。
切换视图
在你的同一个应用程序中来切换到某一个视图,你可以使用AppUi类的ActivateLocalViewL()函数。该函数的参数可以是一个TUid类型变量,下面就是一个切换视图的示例:
const TUid KDemo1ViewId = { 1 }; // 第一个视图的UID ActivateLocalViewL(KDemo1ViewId); // 启动第一个视图
在激活视图动作发生的时候,第一步是新的视图被激活(activated),第二步是前一个活动的视图被移除(deactivated)。这种方法可以让视图以很快的速度的进行切换。当移除视图动作发生的时候,该视图的所有控件,包括菜单和对话框,都要被关闭/析构。系统对话框会作自动处理,自行关闭。如果你需要在对话框即将被关闭的时候保存数据,那么你只需要在对话框中处理EAknSoftkeyCancel命令,即可在对话框被关闭之前保存控件中的数据,而处理之后,删除资源工作将会继续进行。
发送消息
ActivateLocalViewL()函数有一个重载形式可以将消息ID和一段消息内容传递给某一个视图。消息ID是一个TUid类型的变量,通常用来指定传递消息给视图的具体某一个控件或者对话框,用以让该控件或对话框执行某一项命令,而消息内容是一个TDesC8类型的字符串(descriptor),它可以用来在不同视图之间传递数据。下面就是使用范例:
const TUid KViewUid= {1}; const TUid KCustomMessageUid= {2}; TBuf8<255> customMessage; customMessage.Copy(_L8("Some data here")); ActivateLocalViewL(KViewUid, KCustomMessageUid, customMessage);
DoActivateL以及前一视图的ID
视图类中的DoActivateL()函数的目的是创建容器类以及处理传递进入视图的消息ID以及消息内容。除了这些在前一部份中讲到的内容,DoActivateL() 还提供了一个类型为TVwsViewId的参数,用来表示前一个视图的ID。这个参数可以让当前视图返回前一个激活他的视图,而且可以保存前一视图的具体某一个消息ID。比如当前的视图是被其他应用程序的某一个视图启动的,那么当本视图结束后,当前视图可以根据传递进来的前一视图参数,返回相应的呼叫应用程序中去。
DoDeActivateL函数
DoDeActivateL是应用程序中另外一个视图已经被激活,当前视图即将被关闭时被调用的函数。这种顺序使得视图的切换速度变得十分迅速。当DoDeActivateL被调用的时候,该视图已经从视图管理栈中被移除,因此,视图的容器类以及容器类所管理的所有控件,都需要被析构。
使用其他应用程序的视图
激活外部应用程序的某一个视图,可以使用AppUi类的ActivateViewL函数来完成。ActivateViewL()函数和ActivateLocalViewL()函数的使用方法是类似的,唯一不同之处就在于,ActivateViewL()函数使用TVwsViewId类型的参数而ActivateLocalViewL()使用的是TUid类型的参数。TVwsViewId类型的参数,由外部应用程序的UID和该应用程序的视图ID所组成,下面是使用范例:
const TUid KPhotoAlbumUid KGalleryUid = {0x101f8599 0x101F4CD1}; CCoeAppUi::ActivateViewL(TVwsViewId(KGalleryUidKPhotoAlbumUid,TUid::Uid(1))); // ActivateViewL()的调用过程和ActivateLocalViewL()几乎是完全一样的
要想向外部应用程序传递参数,范例如下:
const TUid KCustomMessageUid= {2}; TBuf8<255> customMessage; customMessage.Copy(_L8("Some data here")); const TUid KGalleryUid KPhotoAlbumUid={0x101f8599 0x101F4CD1}; CCoeAppUi::ActivateViewL(TVwsViewId(KGalleryUidKPhotoAlbumUid, TUid::Uid(1)), KCustomMessageUid, customMessage);
当用户退出了被激活的外部应用程序,那么系统将会自动回到原先调用ActivateViewL()函数的地方。