bada千字文应用程序开发教程

 

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

 

 
千字文 应用程序能显示汉字,拼音和汉字 + 拼音三种形式的内容,还配有相应的译文显示和朗读功能。
这篇教程就是给大家演示这个程序是如何开发出来的,主要包括应用程序中的设计模式、界面部分、播放功能部分和事件处理模块的实现。
 
1 千字文中的设计模式
Provider 模式
在这个程序中可以通过点击内容切换按钮来分别显示汉字,拼音和汉字 + 拼音三种形式的内容。利用 bada 平台提供的接口很容易就能够采用 Provider 模式来实现这个功能。 Provider 模式被用于提供不同的数据模式,这样可以将不同的
Osp::Ui::Controls::ListView 中通过 SetItemProvider(const IListViewItemProvider &provider)函数来为ListView设置显示内容的Provider。这样可以将UI显示和数据部分分开,我们可以利用IListViewItemProvider来实现Provider模式。分别用3个类QianZiWenHanZiContentProvier,QianZiWenPinYinContentProviderQianZiWenAllContentProvider来分别提供汉字,拼音和汉字+拼音三种内容,每个类都是继承实现了IListViewItemProvider接口类的。这样每次只需要通过调用SetItemProvider(const IListViewItemProvider &provider)来设置不同的Provider然后刷新ListView就可以了。后续如果还有其它形式的内容需要添加的话,只需要继承实现IListViewItemProvider就可以了。
拿提供汉字的 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 千字文中的播放功能
千字文中一个重要的功能就是当长按某一项时,播放器就从这一项开始播放。这个功能的实现是利用了 Osp::Media::Player SeekTo 函数,调用SeekTo() 函数跳转到对应的播放点开始播放就可以了。所以实现这个功能最麻烦的地方就是要在音频文件中通过手工的方式找到每项的播放时间,记住转换为毫秒。 (long msTime)
这就是每项的句子对应的起始时间点:
//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 的角色。
 
详细的技术点大家可以参考源代码。
 

你可能感兴趣的:(移动开发,职场,休闲,Bada)