Symbian 实现基于传统架构场景切换动画
来源:互联网 发布:科怡软件设置 编辑:程序博客网 时间:2024/06/08 18:33
简介
在symbian界面开发中,我还是比较喜欢实用基于传统结构(Constructing views in traditional architecture)设计界面,虽然这样做比较繁琐,界面基本上是自己画出来的,但是, 这样做的灵活性很高,基本可以实现任何自己想要的界面。一般每一个界面都是一个CCoeControl的对象,通过MakeVisible(TBool)来设置其可见或者隐藏。这样切换当然是很生硬的,如果能在切换的时候加一个转换效果,自然好多了,现在很多软件都有场景切换动画的。可以是滑入滑出,淡入淡出等等!
在基于传统ui架构的模式下,如何切换显示界面
一般切换界面的方法为设置当前界面MakeVisible(EFalse),下一界面MakeVisible(ETRue),还要管理堆栈,以便于响应键盘按键:
CCoeControl * iControl1;
CCoeControl * iControl2;
// Construct
..
iControl2->MakeVisible(ETrue);// show
iControl1->MakeVisible(EFalse);// hide
CAppUI * appui = CEikonEnv::Static()->EikAppUi();
// 注意,这里的CAppUI是你程序的UI类
appui->AddToStackL(iControl2);// 添加到栈中
appui->RemoveFromStack(iControl1);// 移除出栈
..
CCoeControl * iControl1;
CCoeControl * iControl2;
// Construct
..
iControl2->MakeVisible(ETrue);// show
iControl1->MakeVisible(EFalse);// hide
CAppUI * appui = CEikonEnv::Static()->EikAppUi();
// 注意,这里的CAppUI是你程序的UI类
appui->AddToStackL(iControl2);// 添加到栈中
appui->RemoveFromStack(iControl1);// 移除出栈
..
实现场景切换动画的原理
实现场景切换动画,当然需要前后界面的截图,在这两张图上面做文章就可以了,然而,要如何获得这两张图确是个问题,前面这个界面的截图还可以通话获屏幕截图的方法来实现,然而,第二个界面呢?还没有画到界面上的,使用前面的方法是做不到的,我们不能先画到屏幕上,再来截图的。
ps。。既然说到获得屏幕截图,就写一下获得屏幕截图的方法吧:
// Get the screen device
CWsScreenDevice * iScreenDevice = CCoeEnv::Static()->ScreenDevice();
// new instance
iScreenBitmap = new (ELeave) CFbsBitmap;
// push
CleanupStack: ushL(iScreenBitmap);
// create
User: eaveIfError(iScreenBitmap->Create(iScreenDevice->Siz eInPixels(),iScreenDevice->DisplayMode()));
// copy screen to bitmap
User: eaveIfError(iScreenDevice->CopyScreenToBitmap(iScre enBitmap));
// pop
CleanupStack: op(iScreenBitmap);
// Get the screen device
CWsScreenDevice * iScreenDevice = CCoeEnv::Static()->ScreenDevice();
// new instance
iScreenBitmap = new (ELeave) CFbsBitmap;
// push
CleanupStack: ushL(iScreenBitmap);
// create
User: eaveIfError(iScreenBitmap->Create(iScreenDevice->Siz eInPixels(),iScreenDevice->DisplayMode()));
// copy screen to bitmap
User: eaveIfError(iScreenDevice->CopyScreenToBitmap(iScre enBitmap));
// pop
CleanupStack: op(iScreenBitmap);
回到原来的话题,我们可以想办法把控件绘制到位图上面,这样就可以获得截图了。
我当初想的方法就是使用双缓冲,先把控件绘制到位图上,也就是说我自己写一个可以调用的Draw方法,然而,系统控件确没有办法这样实现,例如编辑框等,因为,这些控件是系统去调用它们的Draw函数的。。所以这种方法不可行。
其实,CCoeControl类有提供一个SetGC()函数,可以设置绘图上下文,系统默认设置的是CEikonEnv::Static()->SystemGc();这个gc当然是画到了屏幕上面,我们可以通过调用函数SetGC()设置一个指向一张位图的绘图上下文,这样,就可以获得前后界面的截图了
获得前后界面的截图
/**
* 将一个界面绘制到位图上
*/
void DrowScreenInBitmap(CCoeControl* iScreen,CFbsBitmap * iBitmap){
CleanupStack: ushL(iBitmap);
// 获得屏幕设备
CWsScreenDevice * iScreenDevice = CEikonEnv::Static()->ScreenDevice();
//建立位图设备
CFbsBitmapDevice * iDevice = CFbsBitmapDevice::NewL(iBitmap);
CleanupStack: ushL(iDevice);
// 创建位图设备的绘图上下文
CFbsBitGc * gc = NULL;
User: eaveIfError(iDevice->CreateContext(gc));
CleanupStack: ushL(gc);
// SetGc()函数所使用的绘图上下文必须是指向窗口的,因此,必须对gc做一下映射(mapping)
CWindowToBitmapMappingGc *wbgc = CWindowToBitmapMappingGc::NewL(*iScreenDevice,*gc) ;
CleanupStack: ushL(wbgc);
// 这个是自己定义的函数,对每个控件以及它的所有子控件设置GC
SetGc(iScreen,wbgc);
// 调用重绘,此时,控件绘制到了位图上
iScreen->DrawNow();
// 绘制完之后,设置回原来的GC
SetGc(iScreen,NULL);
CleanupStack: opAndDestroy(wbgc);
CleanupStack: opAndDestroy(gc);
CleanupStack::PopAndDestroy(iDevice);
CleanupStack::Pop(iBitmap);
}
/**
* 为每一控件以及它的所有子控件重新设置gc
*/
void SetGc(CCoeControl * iControl,CWindowToBitmapMappingGc* wsgc){
iControl ->SetGc(wsgc);
TInt count = iControl->CountComponentControls();
if(count == 0){
return;
}
for(TInt index = 0; index < count; ++index){
SetGc(iControl->ComponentControl(index),wsgc);
}
}
/**
* 将一个界面绘制到位图上
*/
void DrowScreenInBitmap(CCoeControl* iScreen,CFbsBitmap * iBitmap){
CleanupStack::PushL(iBitmap);
// 获得屏幕设备
CWsScreenDevice * iScreenDevice = CEikonEnv::Static()->ScreenDevice();
//建立位图设备
CFbsBitmapDevice * iDevice = CFbsBitmapDevice::NewL(iBitmap);
CleanupStack::PushL(iDevice);
// 创建位图设备的绘图上下文
CFbsBitGc * gc = NULL;
User: eaveIfError(iDevice->CreateContext(gc));
CleanupStack::PushL(gc);
// SetGc()函数所使用的绘图上下文必须是指向窗口的,因此,必须对gc做一下映射(mapping)
CWindowToBitmapMappingGc *wbgc = CWindowToBitmapMappingGc::NewL(*iScreenDevice,*gc) ;
CleanupStack::PushL(wbgc);
// 这个是自己定义的函数,对每个控件以及它的所有子控件设置GC
SetGc(iScreen,wbgc);
// 调用重绘,此时,控件绘制到了位图上
iScreen->DrawNow();
// 绘制完之后,设置回原来的GC
SetGc(iScreen,NULL);
CleanupStack::PopAndDestroy(wbgc);
CleanupStack::PopAndDestroy(gc);
CleanupStack::PopAndDestroy(iDevice);
CleanupStack::Pop(iBitmap);
}
/**
* 为每一控件以及它的所有子控件重新设置gc
*/
void SetGc(CCoeControl * iControl,CWindowToBitmapMappingGc* wsgc){
iControl ->SetGc(wsgc);
TInt count = iControl->CountComponentControls();
if(count == 0){
return;
}
for(TInt index = 0; index < count; ++index){
SetGc(iControl->ComponentControl(index),wsgc);
}
}
动画的实现
我们已经可以获得前后界面的截图了,有了这两张截图,我相信动画的实现就比较简单了,对这两张图进行合并,透明什么的,绘制到另一个界面上,这个界面可以用来专门显示场景切换的动画,只要使用一个活动对象或者定时器,动态改变绘制的内容,就可以实现了
- Symbian 实现基于传统架构场景切换动画
- 基于控件的传统symbian OS架构之调试小结
- cocos2dx场景切换动画
- cocos2dx场景切换动画
- cocos2dx 场景切换动画
- 切换场景的动画
- cocos2dx场景切换动画
- Android共享元素场景切换动画的实现
- Android共享元素场景切换动画的实现
- Android共享元素场景切换动画的实现
- cocos2d-x 切换场景动画
- cocos2dx 场景切换动画效果
- IOS CCTransitionScene场景切换动画
- cocos2d-x场景切换动画
- 场景动画切换过渡大全
- unity3d 切换场景过度动画
- cocos-lua 场景切换动画
- Unity3d 切换场景过度动画
- Eclipse总是自动关闭
- jsp中include有两种形式
- 支持更多客户端,puppet之mongrel+nginx模式
- android sd卡读写 附源码
- 计算机发展史
- Symbian 实现基于传统架构场景切换动画
- 说说前两天干的搓事!
- S3C6410 ADS1.2 下裸奔 1
- jpa级联保存更新
- ToolTip自定义
- JSF2自定义组件编程系列 第三部分
- 解决方案:用户 'sa' 登录失败。原因: 未与信任 SQL Server 连接相关联
- QT中关于信号与槽机制的实现原理
- h264解码实现了