自定义控件: 滚动条(五)
From Forum Nokia Wiki
| ID | CS000869 | Creation date | March 28, 2008 |
| Platform | S60 3rd Edition, FP1 | Tested on devices | Nokia N95 |
| Category | Symbian C++ | Subcategory | UI |
| Keywords (APIs, classes, methods, functions): CCoeControl, TKeyEvent, CEikScrollBarFrame, TAknDoubleSpanScrollBarModel |
概述
这个代码片段演示如何给有自定义控件的容器控件添加滚动条,以及如何只显示可见部件并在视图的顶部和底部搜查更多的可视部件。
本例扩展了已存代码片段自定义控件: 聚焦(四)。查看本文的“参见”部分以了解自定义控件系列的其它代码片段。
CMyContainerControl - 头文件
添加这些方法和成员数据到CMyContainerControl部件的头文件中。
MoveFocusUpL() 移动焦点寻求更多的部件以显示到视图顶部屏幕
MoveFocusDownL() 移动焦点寻求更多部件以显示到视图底部屏幕
UpdateScrollBarFrameL() 更新滚动条
ShowNextItem() 查找更多条目并在视图底部屏幕显示出来
ShowPrevItem() 查找更多条目并在视图顶部屏幕显示出来
#include <eiksbfrm.h> private: void ShowNextItem(); void ShowPrevItem(); void MoveFocusUpL(); void MoveFocusDownL(); void UpdateScrollBarFrameL(); private: CEikScrollBarFrame* iScrollBarFrame; TAknDoubleSpanScrollBarModel iHDsSbarModel; TAknDoubleSpanScrollBarModel iVDsSbarModel; TInt iFocusedIndex;
CMyContainerControl - 源代码
在CMyContainerControl::ConstructL()中创建滚动条:
// Creating Scroll Bars iScrollBarFrame = new ( ELeave ) CEikScrollBarFrame( this, NULL ); iScrollBarFrame->CreateDoubleSpanScrollBarsL( ETrue, EFalse ); iScrollBarFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan ); iScrollBarFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff );
在CMyContainerControl::UpdateScrollBarFrameL()中更新滚动条数据; 在添加部件到这个容器控件后,这个方法会在CMyContainerControl::AddControlL()中调用。
void CMyContainerControl::UpdateScrollBarFrameL() { TInt controlsHeight = 0; // Height of the controls TInt height = 0; // This view height // Calculate components height CCoeControlArray::TCursor cursor = Components().Begin(); CCoeControl* ctrl = NULL; while ((ctrl = cursor.Control<CCoeControl>()) != NULL) { controlsHeight += ctrl->MinimumSize().iHeight; cursor.Next(); } // This view height height = Rect().Height(); // Set teh scrollbar visible if fields do not fit the screen if( controlsHeight > height && iScrollBarFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOff) { iScrollBarFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, // horizontal CEikScrollBarFrame::EOn); // vertical } // Hide the scrollbar if fields fit the screen else if ( controlsHeight <= height && iScrollBarFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn) { iScrollBarFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, // horizontal CEikScrollBarFrame::EOff); // vertical } // Update scroll bar position iVDsSbarModel.SetScrollSpan(Components().Count()); iVDsSbarModel.SetWindowSize(1); iVDsSbarModel.SetFocusPosition(iFocusedIndex); TEikScrollBarFrameLayout layout; layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant; TRect rect = Rect(); iScrollBarFrame->TileL(&iHDsSbarModel,&iVDsSbarModel,rect,rect,layout); iScrollBarFrame->SetVFocusPosToThumbPos(iVDsSbarModel.FocusPosition()); }
CMyContainerControl::MoveFocusUpL()移动活动部件焦点,以及若达到屏幕顶部就请求显示更多部件。
void CMyContainerControl::MoveFocusUpL() { CCoeControlArray::TCursor cursor = Components().Begin(); CCoeControl* ctrl = NULL; CCoeControl* prevCtrl = NULL; while ((ctrl = cursor.Control<CCoeControl>()) != NULL) { if (ctrl->IsFocused()) { if (prevCtrl) { // Set focus to previous control ctrl->SetFocus(EFalse); prevCtrl->SetFocus(ETrue); iFocusedIndex--; // Focus is over the view? if (iFocusedIndex > 0 && !prevCtrl->IsVisible()) { ShowPrevItem(); } break; } else { break; // First control is already focused } } prevCtrl = ctrl; cursor.Next(); } UpdateScrollBarFrameL(); }
CMyContainerControl::MoveFocusDownL()移动活动部件焦点,以及若焦点到达屏幕底部就请求显示更多部件。
void CMyContainerControl::MoveFocusDownL() { CCoeControlArray::TCursor cursor = Components().Begin(); CCoeControl* ctrl = NULL; CCoeControl* nextCtrl = NULL; while ((ctrl = cursor.Control<CCoeControl>()) != NULL) { if (ctrl && ctrl->IsFocused()) { cursor.Next(); nextCtrl = cursor.Control<CCoeControl>(); if (nextCtrl) { // Set focus to next control ctrl->SetFocus(EFalse); nextCtrl->SetFocus(ETrue); iFocusedIndex++; // Focus is over the view? if (!nextCtrl->IsVisible()) { ShowNextItem(); } break; } else { break; // Last control is already focused } } cursor.Next(); } UpdateScrollBarFrameL(); }
void CMyContainerControl::ShowNextItem()和void CMyContainerControl::ShowPrevItem()查找更多的部件以便查看及设置到正确的位置。
void CMyContainerControl::ShowNextItem() { TPoint position; // Goes throught all components of this container control CCoeControlArray::TCursor cursor = Components().Begin(); CCoeControl* ctrl = NULL; TBool focusedFound = EFalse; while ((ctrl = cursor.Control<CCoeControl>()) != NULL) { if (ctrl && ctrl->IsFocused()) { focusedFound = ETrue; } if (focusedFound) { // Set size TSize size = ctrl->MinimumSize(); size.SetSize(Rect().Width(),size.iHeight); ctrl->SetSize(size); // Does it fit to the screen? if ((position.iY + size.iHeight) >= Rect().iBr.iY) { ctrl->MakeVisible(EFalse); focusedFound = EFalse; // Let rest components be MakeVisible(EFalse) } else { ctrl->MakeVisible(ETrue); // Set position ctrl->SetPosition(position); // Store position of last component position.iY += size.iHeight; } } else { ctrl->MakeVisible(EFalse); } cursor.Next(); } } void CMyContainerControl::ShowPrevItem() { TPoint position; position.iY = Rect().iBr.iY; // Goes throught all components from the last -> to the first one CCoeControlArray::TCursor cursor = Components().End(); CCoeControl* ctrl = NULL; TBool focusedFound = EFalse; while (cursor.Prev()) { ctrl = cursor.Control<CCoeControl>(); if (ctrl && ctrl->IsFocused()) { focusedFound = ETrue; } if (focusedFound) { // Set size TSize size = ctrl->MinimumSize(); size.SetSize(Rect().Width(),size.iHeight); ctrl->SetSize(size); // Fix position position.iY -= size.iHeight; if ((position.iY) <= Rect().iTl.iY-2) { // Does not fit anymore ctrl->MakeVisible(EFalse); focusedFound = EFalse; // Let rest components be MakeVisible(EFalse) } else { ctrl->MakeVisible(ETrue); // Set position ctrl->SetPosition(position); } } else { ctrl->MakeVisible(EFalse); } } }
后置条件
自定义控件有滚动条演示视图中焦点的位置。当达到视图的底部或顶部将显示更多部件。
参见
自定义控件系列:
- 自定义控件: 定义(一) 定义自定义控件
- 自定义控件: 从资源构造(二) 从资源创建控件
- 自定义控件: 容器控件(三) 创建容器控件
- 自定义控件: 聚焦(四) 处理摁键事件和改变活动自定义控件焦点
- 自定义控件: 在Dialog中(六) 把自定义控件加到CAknDialog
- Image:CustomControl.zip 样例代码补丁

