Symbian學(xué)習(xí)筆記(10)——使用ListBox
先聲明一個列表組件:CAknSingleStyleListBox* iListBox;
然后在Container的ConstructL中去創(chuàng)建它:
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()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOn,CEikScrollBarFrame::EOn);
iListBox->ItemDrawer()->ColumnData()->EnableMarqueeL(ETrue);
iListBox->SetRect(aRect);
SetRect(aRect);
ActivateL();
}
這里有幾句話,一是SetScrollBarVisibilityL設(shè)置使用滾動條,二是ItemDrawer()->ColumData()->EnableMarqueeL()讓選中的文本超長后可以左右滾動。
有一點比較奇怪,我得先設(shè)置ListBox的Rect才能設(shè)置整個Container的Rect?否則ListBox會不占整個主面板的位置。
接著在合適的地方需要去給ListBox增加內(nèi)容:
...{
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"。這里的格式似乎挺重要的,一般是:圖標(biāo)ID\t題頭字串\t主要字串\t圖標(biāo)ID\t圖標(biāo)ID。
我這里因為沒有用到圖標(biāo)所以是一個\t%S,這個\t不可省略。如果用圖標(biāo),則變成%d\t%S了,同時還要增加iconArray在創(chuàng)建iListBox的時候。
CleanupStack::PushL(icons);
icons->ConstructFromResourceL(R_ICON_LISTICONS);
iListBox->ItemDrawer()->ColumnData()->SetIconArray(icons);
CleanupStack::Pop();
在ListBox中有一個叫Model()的還有一個叫View()的,從名字上就可以看出它們的含義了。前面我們從Model中操作列表內(nèi)容,而我們可以從View中獲取ItemDrawer去操作列表顯示
的一些參數(shù),但是我覺得有一點不爽的是,缺省生成的列表框字體比較大,不是太喜歡,在網(wǎng)上搜了一下,似乎那個設(shè)置字體的方法對我的機(jī)器不管用?
不過有一種方法是可行的,只是比較麻煩,那就是自己去實現(xiàn)ListBox,以及它的ItemDrawer。在網(wǎng)上看到的代碼我試了一下,還行。方法如下。
第一步作一個自己的ItemDrawer:
...{
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;
};
實現(xiàn)的代碼中最重要的就是那個DrawActualItem方法負(fù)責(zé)具體的繪制工作,從它的參數(shù)表中足夠得到繪制所需的信息,剩下的事情就是用SystemGc去繪制。
第二步是作一個自己的ListBox控件:
...{
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()中創(chuàng)建成員iItemDrawer = new (ELeave) CCustomListItemDrawer(*this)。而OfferKeyEvent主要的作用是處理上下方向鍵。
關(guān)于ListBox的使用,可以參考這個地址:http://pagesperso-orange.fr/klisa/3650/ListBox/page01.html
【編輯推薦】