千字文
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
的角色。
詳細的技術點你們能夠參考源代碼。