Symbian中關於ListBox的編程使用

    在Symbian系統中,ListBox的使用是比較複雜的,也是比較常用的,應該先從最簡單的CAknSingleStyleListBox入手來嘗試。基本實現步驟就是:先聲明一個列表組件CAknSingleStyleListBox* iListBox,然後在Container的ConstructL中去創建它,接着在合適的地方需要去給ListBox增加內容。具體編程如下:

    先聲明一個列表組件:CAknSingleStyleListBox* iListBox;
    然後在Container的ConstructL中去創建它:

void CUniNewsAppContainer::ConstructL(const TRect& aRect)
{
    CreateWindowL();

    //add your code here ...

    //construct a listbox
    iListBox = new(ELeave) CAknSingleStyleListBox;
    iListBox->SetContainerWindowL( *this);
    iListBox->SetListBoxObserver(this);
    iListBox->ConstructL(this,EAknListBoxSelectionList|EAknListBoxLoopScrolling);
    iListBox->CreateScrollBarFrameL(ETrue);
    iListBox->ScrollBarFrame()->SetScrollBarVisibilityLCEikScrollBarFrame::EOn,CEikScrollBarFrame::EOn);
    iListBox->ItemDrawer()->ColumnData()->EnableMarqueeL(ETrue);
    iListBox->SetRect(aRect);
    SetRect(aRect);
    ActivateL();
}

    這裏有幾句話:
    一是SetScrollBarVisibilityL設置使用滾動條;
    二是ItemDrawer()->ColumData()->EnableMarqueeL()讓選中的文本超長後可以左右滾動。
    有一點比較奇怪,我得先設置ListBox的Rect才能設置整個Container的Rect?否則ListBox會不佔整個主面板的位置。

    接着在合適的地方需要去給ListBox增加內容:

void CUniNewsAppContainer::InitListBox(TInt tabId)
{
    if(iListBox==NULL) return;
    CDesCArray* list = static_cast<CDesCArray*>( iListBox->Model()->ItemTextArray() );
    TBuf<256> str;
    list->Reset();
    CUniNewsAppView * appView = STATIC_CAST(CUniNewsAppUi*,iCoeEnv->AppUi())->iAppView;
    RArray<TNewsContent>* rc = appView->iChannelHandler->GetContents();
    for(TInt i=0;i<rc->Count();i++)
    {
        if((*rc)[i].pid==tabId)
        {
            str.FillZ(str.MaxLength());
            str.Format(KITEMFORMAT,(*rc)[i].title);
            list->AppendL(str);
        }
    }
    iListBox->HandleItemAdditionL();
    iListBox->SetFocus( ETrue );
    iListBox->SetCurrentItemIndexAndDraw(appView->iListIndex);
    iListBox->ActivateL();
    iListBox->DrawNow();
}

    這裏的HandleItemAdditionL()通知一下ListBox模型作了增加操作,同樣還有一個HandleItemRemovalL()則是通知ListBox作了一個刪除操作。
    這裏的KITEMFORMAT定義是"/t%S"。這裏的格式似乎挺重要的,一般是:圖標ID/t題頭字串/t主要字串/t圖標ID/t圖標ID。
    因爲沒有用到圖標所以是一個/t%S,這個/t不可省略。如果用圖標,則變成%d/t%S了,同時還要增加iconArray在創建iListBox的時候。

    CAknIconArray* icons =new(ELeave) CAknIconArray(2);
    CleanupStack::PushL(icons);
    icons->ConstructFromResourceL(R_ICON_LISTICONS);
    iListBox->ItemDrawer()->ColumnData()->SetIconArray(icons);
    CleanupStack::Pop();

    在ListBox中有一個叫Model()的還有一個叫View()的,從名字上就可以看出它們的含義了。前面我們從Model中操作列表內容,而我們可以從View中獲取ItemDrawer去操作列表顯示的一些參數:
    iListBox->ItemDrawer()->SetFont(ApacPlain12());
    但是我覺得有一點不爽的是,缺省生成的列表框字體比較大,不是太喜歡,在網上搜了一下,似乎那個設置字體的方法對我的機器不管用?
    不過有一種方法是可行的,只是比較麻煩,那就是自己去實現ListBox,以及它的ItemDrawer。在網上看到的代碼我試了一下,還行。方法如下。

    第一步作一個自己的ItemDrawer:
class CCustomListItemDrawer: public CListItemDrawer
{
public:
    CCustomListItemDrawer(const CEikTextListBox& aListBox);
    ~CCustomListItemDrawer();

private:
    virtual void DrawActualItem(TInt aItemIndex, const TRect& aActualItemRect, TBool aItemIsCurrent, TBool aViewIsEmphasized, TBool aViewIsDimmed, TBool aItemIsSelected) const;

public:
    void SetIconArray(CArrayPtr<CGulIcon>* aIconArray);
TSize MaxIconSize() const;

private:
    void DeleteIconArray();
    void CalculateMaxIconSize();

private:
    const CEikTextListBox& iListBox;
    CArrayPtr<CGulIcon>* iIconArray;
    TSize iMaxIconSize;
};

    實現的代碼中最重要的就是那個DrawActualItem方法負責具體的繪製工作,從它的參數表中足夠得到繪製所需的信息,剩下的事情就是用SystemGc去繪製。

    第二步是作一個自己的ListBox控件:
class CCustomListBox: public CEikTextListBox
{
public: // constructors
    CCustomListBox();
    void ConstructL(const CCoeControl* aParent, TInt aFlags = 0);

public: // from CEikTextListBox
    virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);

private: // from CEikTextListBox
    virtual void CreateItemDrawerL();
};

    在它的CreateItemDrawerL()中創建成員iItemDrawer = new (ELeave) CCustomListItemDrawer(*this)。而OfferKeyEvent主要的作用是處理上下方向鍵。

發佈了3 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章