千字文
bada
应用程序开发教程
概述:
“
千字文
”
是一个电子书应用程序,将中国传统的《千字文》作到了
bada
平台上,方便广大的
bada
手机用户随时随地阅读学习。


“
千字文
”
应用程序能显示汉字,拼音和汉字
+
拼音三种形式的内容,还配有相应的译文显示和朗读功能。
这篇教程就是给你们演示这个程序是如何开发出来的,主要包括应用程序中的设计模式、界面部分、播放功能部分和事件处理模块的实现。
1
,
”
千字文
”
中的设计模式
Provider
模式
在这个程序中能够经过点击
”
内容切换
”
按钮来分别显示汉字,拼音和汉字
+
拼音三种形式的内容。利用
bada
平台提供的接口很容易就可以采用
Provider
模式来实现这个功能。
Provider
模式被用于提供不一样的数据模式,这样能够将不一样的
拿提供汉字的
Provider
举例,其它的
Provider
和它相似。
class
QianZiWenHanZiContentProvider
:
public
Osp::Ui::Controls::
IListViewItemProvider
{
public
:
QianZiWenHanZiContentProvider();
virtual
~QianZiWenHanZiContentProvider();
public
:
virtual
int
GetItemCount(
void
);
virtual
Osp::Ui::Controls::
ListItemBase
* CreateItem(
int
index,
int
itemWidth);
virtual
bool
DeleteItem(
int
index, Osp::Ui::Controls::
ListItemBase
* pItem,
int
itemWidth);
};
在监听到
”
切换内容
”
事件时替换
Provider
并刷新界面就能够了。
void
QianZiWenDisplayForm::ChangeContentType
()
{
if
(
__contentStyle
==
CONTENT_STYLE_HANZHI
)
{
delete
__pContentProvider
;
__pContentProvider
= NULL;
__pContentProvider
=
new
QianZiWenPinYinContentProvider();
__pListPanel
->SetContentProvider(
__pContentProvider
);
__pListPanel
->UpdateDisplayPanel();
__contentStyle
=
CONTENT_STYLE_PINYIN
;
}
else
if
(
__contentStyle
==
CONTENT_STYLE_PINYIN
)
{
delete
__pContentProvider
;
__pContentProvider
= NULL;
__pContentProvider
=
new
QianZiWenAllContentProvider();
__pListPanel->SetContentProvider(
__pContentProvider
);
__pListPanel
->UpdateDisplayPanel();
__contentStyle
=
CONTENT_STYLE_ALL
;
}
else
if
(
__contentStyle
==
CONTENT_STYLE_ALL
)
{
delete
__pContentProvider
;
__pContentProvider
= NULL;
__pContentProvider
=
new
QianZiWenHanZiContentProvider();
__pListPanel
->SetContentProvider(
__pContentProvider
);
__pListPanel
->UpdateDisplayPanel();
__contentStyle
=
CONTENT_STYLE_HANZHI
;
}
}
2
,
”
千字文
”
中的界面实现
(1)
Footer
建立
Footer,
void
QianZiWenDisplayForm::CreateFooter
()
{
//Creat the footer items
Footer
* pFooter =
GetFooter
();
pFooter->
SetStyle
(
FOOTER_STYLE_BUTTON_TEXT
);
FooterItem
switchItem;
switchItem.
Construct
(ID_BUTTON_SWITCH);
switchItem.
SetText
(L
"
切换内容
"
);
pFooter->
InsertItemAt
(INDEX_BUTTON_SWITCH,switchItem);
FooterItem
playItem;
playItem.
Construct
(ID_BUTTON_PLAY);
playItem.
SetText
(L
"
播放
"
);
pFooter->
InsertItemAt
(INDEX_BUTTON_PLAYER,playItem);
FooterItem
helpItem;
helpItem.
Construct
(ID_BUTTON_HELP);
helpItem.
SetText
(L
"
帮助
"
);
pFooter->
InsertItemAt
(INDEX_BUTTON_HELP,helpItem);
pFooter->
AddActionEventListener
(*
this
);
}
其中用于控制播放器的
”
播放
”
和
”
暂停
”
按钮须要进行状态的改变,由播放转变成暂停,再由暂停转变成播放。这时须要进行改变和更新。
void
QianZiWenDisplayForm::ChangeToPause
()
{
//Change the footer item
Footer
* pFooter =
GetFooter
();
FooterItem
pauseItem;
pauseItem.
Construct
(ID_BUTTON_PAUSE);
pauseItem.
SetText
(L
"
暂停
"
);
pFooter->
SetItemAt
(INDEX_BUTTON_PLAYER,pauseItem);
pFooter->
RequestRedraw
();
}
void
QianZiWenDisplayForm::ChangeToPlay
()
{
//Change the item
Footer
* pFooter =
GetFooter
();
FooterItem
playItem;
playItem.
Construct
(ID_BUTTON_PLAY);
playItem.
SetText
(L
"
播放
"
);
pFooter->
SetItemAt
(INDEX_BUTTON_PLAYER,playItem);
pFooter->
RequestRedraw
();
}
(2)
Panel
和
ListView
“
千字文
”
程序中没有直接将
ListView
添加到
Form
当中,而是根据
Form
的客户区域建立了一个
Panel
并添加到
Form
当中,而后在
Panel
中建立
ListView
并将
Panel
设置为其容器类控件。
建立
Panel
class
QianZiWenDisplayPanel
:
public
Osp::Ui::Controls::
Panel
{
public
:
QianZiWenDisplayPanel(Osp::Ui::Controls::
IListViewItemEventListener
* pListener,Osp::Ui::
ITouchEventListener
* pTouchListener);
virtual
~QianZiWenDisplayPanel();
public
:
virtual
result
OnInitializing(
void
);
virtual
result
OnTerminating(
void
);
virtual
result
OnDraw();
public
:
void
SetContentProvider(Osp::Ui::Controls::
IListViewItemProvider
* pProvider);
void
UpdateDisplayPanel();
int
GetItemIndexFromPosition(
const
Osp::Graphics::
Point
& position);
private
:
//Own
Osp::Graphics::
Bitmap
*
__pBgBmp
;
Osp::Ui::Controls::
ListView
*
__pContentList
;
//Not Own
Osp::Ui::Controls::
IListViewItemProvider
*
__pContentProvider
;
//Not Own
Osp::Ui::Controls::
IListViewItemEventListener
*
__pListListener
;
//Not Own
Osp::Ui::
ITouchEventListener
*
__pTouchListener
;
};
在
Panel
中建立
ListView
result
QianZiWenDisplayPanel::OnInitializing(
void
)
{
result
r = E_SUCCESS;
SetBackgroundColor
(
Color
::
COLOR_WHITE
);
//Get the background bitmap
AppResource
* pAppRes =
Application
::
GetInstance
()->
GetAppResource
();
__pBgBmp
= pAppRes->
GetBitmapN
(L
"bg.png"
);
//Create the List
__pContentList
=
new
ListView
();
Rectangle
rec =
GetBounds
();
__pContentList
->
Construct
(rec,
true
,
false
);
__pContentList
->
SetItemProvider
(*
__pContentProvider
);
__pContentList
->
AddListViewItemEventListener
(*
__pListListener
);
__pContentList
->
AddTouchEventListener
(*
__pTouchListener
);
AddControl
(*
__pContentList
);
return
r;
}
3
,
”
千字文
”
中的播放功能
这就是每项的句子对应的起始时间点:
//The starting positon of each sentence in the audio file
//Change the positon value(hh:mm:ss) to milliseconds
const
int
StartPosition[ListItemCount] =
{
3000,
//1
8000,
13000,
18000,
……
};
看一下代码实现:
void
QianZiWenDisplayForm::OnListViewItemLongPressed
(Osp::Ui::Controls::
ListView
&listView,
int
index,
int
elementId,
bool
& invokeListViewItemCallback)
{
int
position = StartPosition[index];
__pAudioPlayer
->
SeekTo
(position);
}
因为
SeetkTo
是一个异步调用的过程,因此须要在相应的完成回调函数中调用
Player
进行播放。
void
QianZiWenDisplayForm::OnPlayerSeekCompleted
(
result
r )
{
AppLog(
"OnPlayerSeekCompleted"
);
if
(r == E_SUCCESS)
{
AppLog(
"OnPlayerSeekCompleted Success"
);
if
(
__pAudioPlayer
->
GetState
() ==
PLAYER_STATE_PAUSED
)
{
__pAudioPlayer
->
Play
();
//Change the item
ChangeToPause();
}
}
}
4
,
”
千字文
”
中的事件处理
程序中用
QianZiWenDisplayForm
类继承实现了全部的接口了,包括有
Osp::Ui::IActionEventListener,Osp::Ui::Controls::IListViewItemEventListener,Osp::Media::IPlayerEventListener,Osp::Ui::ITouchEventListener,
这样作的好处就是能够将事件处理和
UI
的现实部分进行分离,单独拿出一个类来进行事件处理,比起将事件处理分散在各个类分别进行处理更易于管理。也符合
MVC
中的
View
和
Controller
分离的原则。因此
QianZiWenDisplayForm
扮演了一个
Controller
的角色。
详细的技术点你们能够参考源代码。