阅读更多 仍是做一个同样界面同样功能的数独游戏,但是所花费的时间远远超出我用Android或者J2ME来做同样的事情,当然运行效率也很明显(我将J2ME实现的数独放在N73上跑过,因为重绘屏幕的代码没有优化,所以效果不好,但同样的算法在BREW或者Symbian上就跑得相当顺畅)。

言归正传,关于数独在Android上的实现,可参考这个:
http://blog.csdn.net/sharetop/archive/2008/02/27/2124153.aspx

这次我主要谈谈在做这个 Symbian版本中遇到的几个问题,希望以后自己不要再犯同样的错误了。

1、多视图的应用程序框架的问题
我用的是Carbide C++ IDE环境,不知道为什么不能生成多视图的架子,所以只能在HelloWorld框架的代码上自己手工改写,结果就弄出一个Panic折腾了我很久,问题出在 千万不要在析构函数中去删除创建的CAknView,如下代码(注掉是正确的,否则就在退出应用时会出错):
CSuDoScAppUi:: ~ CSuDoScAppUi()
... {
//if(iAppCtrol!=NULL){
//this->RemoveView(iAppCtrol->Id());
//deleteiAppCtrol;
//iAppCtrol=NULL;
//
//RDebug::Printf("deleteiAppCtrol");
//}
//RDebug::Printf("deleteUi");
}

我们需要负责清除对象的地方是在CAknView中负责删掉CCoeControl,因为在它的DoActivateL/DoDeactivateL两个函数中负责创建和删除CoeControl,但是如果退出时这个DoDeactivateL是不会主动调用的,因此在析构时可以调用一下它:
CSuDoScAppCtrol:: ~ CSuDoScAppCtrol()
... {
iFs.Close();
iList.Close();

DoDeactivate();

RDebug::Printf(
"deleteCtrol");
}

2、关于显示字体的问题
在调用CWindowGc的DrawText方法时, 必须要设置一下字体否则不会有东西显示出来,而设置字体有一段标准代码可以参考(来源于网上):
CWindowGc & gc = SystemGc();
CFont
* font = NULL;
TFontSpecfontSpec
= iEikonEnv -> LegendFont() -> FontSpecInTwips();
fontSpec.iHeight
-= fontSpec.iHeight / 6 ;

iCoeEnv
-> ScreenDevice() -> GetNearestFontInTwips(font,fontSpec);
gc.UseFont(font);

// dosth.

gc.DiscardFont();
iCoeEnv
-> ScreenDevice() -> ReleaseFont(font);
3、关于SVG图像的显示
我将所有的数字小图片都做成SVG格式, 在显示SVG图像的时候必须设置它的尺寸,否则也无法显示。另外,因为制作时它的背景色为白色,所以要显示为透明则需要用到它的MASK了。
for (TInti = 0 ,j = 0 ;i < 9 ;i ++ ,j += 2 ) ... {
CFbsBitmap
*b=NULL;
CFbsBitmap
*c=NULL;
AknIconUtils::CreateIconL(b,c,iMFileName,EMbmSudoscY1
+j,EMbmSudoscY1+j+1);
AknIconUtils::SetSize(b,TSize(
22,22));
AknIconUtils::SetSize(c,TSize(
22,22));
iThumbNormal.AppendL(b);
iThumbNormalMask.AppendL(c);
}

iThumbNormal和iThumbNormalMask是两个RPointerArray对象,这里我在ContructL时就加载所有的数字图,这种方法可以有效地减轻在重绘时加载照成的闪屏。然后在显示时这样即可:
if (CSuDoScHelper::CheckGrid(iGrid,i % 9 ,i / 9 ,iGrid[i].value))
gc.BitBltMasked(TPoint(xx,yy),iThumbNormal[iGrid[i].value
- 1 ],r,iThumbNormalMask[iGrid[i].value - 1 ],EFalse);
else
gc.BitBltMasked(TPoint(xx,yy),iThumbError[iGrid[i].value
- 1 ],r,iThumbErrorMask[iGrid[i].value - 1 ],EFalse);

4、关于按键处理
我仍是按BREW手机的模式,左软键菜单,右软键切换模式,*#则用来切换题目。在Symbian中对键值的定义比其它平台要复杂一些,让人有点摸不着头脑,比如数字健没有定义在头文件中(不是那个EStdKeyNkp1等枚举),只能自己去尝试一下:
TKeyResponseCSuDoScAppView::OfferKeyEventL( const TKeyEvent & aKeyEvent,TEventCodeaType)
... {
if(aType==EEventKeyUp)
...{
if(aKeyEvent.iScanCode>=EStdKeyLeftArrow&&aKeyEvent.iScanCode<=EStdKeyDownArrow)
returnTreatNavKey(aKeyEvent,aType);
elseif(aKeyEvent.iScanCode>=48&&aKeyEvent.iScanCode<=57)
returnTreatNumKey(aKeyEvent,aType);
elseif(aKeyEvent.iScanCode==EStdKeyDevice1||aKeyEvent.iScanCode==EStdKeyHash||aKeyEvent.iScanCode==EStdKeyNkpAsterisk)
returnTreatChrKey(aKeyEvent,aType);
}

returnEKeyWasConsumed;
}

5、关于消息对话框
在显示“解题成功”的对话框时,记得不要画蛇添足地去消除对话框,如下面代码中注掉的代码是多余的:
TBoolCSuDoScAppView::ShowSuccessDlg()
... {
if(iState==EGSTATE_WRITE&&CSuDoScHelper::CheckSuccess(iGrid))...{
TBuf
<32>str;
iCoeEnv
->ReadResource(str,R_TEXT_SUCCESS);
CAknInformationNote
*dlg=new(ELeave)CAknInformationNote(ETrue);
//CleanupStack::PushL(dlg);

dlg
->ExecuteLD(str);
//CleanupStack::PopAndDestroy(1);

returnETrue;
}

returnEFalse;
}

暂时就这些吧。

更多相关文章

  1. Android(安卓)Native进程间通信实例—Socket本地通信服务端进程
  2. Android如何防止apk程序被反编译(尊重劳动成果)
  3. 又撸一年的代码!尽管我秃头还白发,我还是坚持了
  4. Android(安卓)将应用加入到分享列表 跳转的市场选择列表
  5. android语音即时通讯之录音、播放功能实现代码
  6. Android(安卓)TextView标点符号换行问题(顺便学习Android自定义Vi
  7. Android(安卓)jni/ndk编程一:jni初级认识与实战体验
  8. [Android开发] 实现点击缩略图查看大图的功能
  9. React native 与Android原生交互方式(一)

随机推荐

  1. 如何使用Android(安卓)Studio开发/调试An
  2. Android读写XML(下)——创建XML文档
  3. 在 Android(安卓)上使用 XML 和 JSON,第 1
  4. 编译Android最新源码(090508)
  5. Android中读取电话本Contacts联系人的所
  6. Android(安卓)学习指南
  7. 谷歌Android三季度市场份额升至17%
  8. Android体系结构
  9. Android(安卓)ListView滑动后背景变黑问
  10. Android开发模式:MVP Vs MVVM