S60上的带鱼眼放大效果列表

首先要强烈鄙视一下给Nokia S60设计UI接口团队——用到现在最恶心的,文档最不完整的UI框架了。

 

然后要感谢一下Forum Nokia Wiki 上的 Mayank , 提供了一个鱼眼列表的范例程序,虽然有bug。

 

http://wiki.forum.nokia.com/index.php/How_to_implement_fisheye_view

 

源代码可在上面地址下到

 

这里说一下这个范例里的bug

 

如果列表很大,超出屏幕,那么最后一个可能没法显示全。

 

原因是父类的View只能按照等高度的item布局,鱼眼放大效果其实是在绘制过程中的hack方法,实际上view不知道我们放大了某个item。

 

修复方法是,如果这个焦点在当前屏幕内的最后一行(注意不是全部列表最后一行),那么改变调整逻辑,把列表下移腾出放大空间,改成列表上移。

 

这个调整后,范例里的Relign方法就没用了,改善了处理效率。

 

最后改进一下列表的Draw方法。

 

List控件的Draw方法必调用列表项绘制方法,否则是看不到内容的。

 

但是没必要全部都绘制一边。只要画当前屏幕开始项目和结束项目就行了。

 

这些改动,都已经放到wiki上了。不过需要手工覆盖到范例上。

 

void
 CCustomListItemDrawer::DrawActualItem
(
TInt aItemIndex,	const
 TRect& aActualItemRect,
TBool aItemIsCurrent, TBool /*aViewIsEmphasized*/ ,
TBool /*aViewIsDimmed*/ , TBool aItemIsSelected) const
{
TInt selectedIndex = iListBox.CurrentItemIndex ( ) ;
TInt itemIndex = aItemIndex;
TRect itemRect = aActualItemRect;

if ( selectedIndex == iListBox.BottomItemIndex ( ) ) {
// selected item is at the bottom
itemRect.iTl .iY -= iItemCellSize.iHeight ;
if ( itemIndex < selectedIndex ) {
itemRect.iBr .iY -= iItemCellSize.iHeight ;
}
} else {
if ( aItemIsCurrent) {
itemRect.iBr .iY += iItemCellSize.iHeight ;
} else if ( itemIndex > selectedIndex) {
// Lets move the following entries down to accomodate fish eye window
itemRect.iTl .iY += iItemCellSize.iHeight ;
itemRect.iBr .iY += iItemCellSize.iHeight ;
}
}
// Call the Actual draw function
}
 
CFishEyeListBox::CFishEyeListBox ( )
:CAknSingleHeadingStyleListBox( )
{
}
 
/**
* Override the default item drawer by our own
*/

void CFishEyeListBox::CreateItemDrawerL ( )
{
CColumnListBoxData* columnData = CColumnListBoxData::NewL ( ) ; // CColumnListBoxItemDrawer owns columnData
const CFont* myFont = CEikonEnv::Static ( ) ->DenseFont( ) ;
iItemDrawer = new ( ELeave) CCustomListItemDrawer( Model( ) , myFont, columnData, *this ) ;
}
 
/**
* To handle the item scrolling
*/

TKeyResponse CFishEyeListBox::OfferKeyEventL ( const TKeyEvent& aKeyEvent,
TEventCode aType) {
if ( EEventKey == aType) {
switch ( aKeyEvent.iCode ) {
// Down arrow
case EKeyDownArrow: {
ScrollDown( ) ;
DrawDeferred( ) ;
return EKeyWasConsumed;
}
 
// Up arrow
case EKeyUpArrow: {
ScrollUp( ) ;
DrawDeferred( ) ;
return EKeyWasConsumed;
}
 
default :
return CEikTextListBox::OfferKeyEventL ( aKeyEvent, aType) ;
}
}
return EKeyWasNotConsumed;
}
 
void CFishEyeListBox::ScrollDown ( void ) {
TInt currIndex = CurrentItemIndex( ) ;
if ( currIndex < Model( ) ->NumberOfItems( ) - 1 ) {
SetCurrentItemIndex( currIndex + 1 ) ;
} else {
// Lets do circular scrolling by setting current index as the first item
SetCurrentItemIndex( 0 ) ;
}
ScrollToMakeItemVisible( CurrentItemIndex( ) ) ;
}
void CFishEyeListBox::ScrollUp ( void ) {
TInt currIndex = CurrentItemIndex( ) ;
if ( currIndex > 0 ) {
SetCurrentItemIndex( currIndex - 1 ) ;
} else if ( Model( ) ->NumberOfItems( ) > 0 ) {
// Lets do circular scrolling by setting current index as the last item
SetCurrentItemIndex( Model( ) ->NumberOfItems( ) - 1 ) ;
}
ScrollToMakeItemVisible( CurrentItemIndex( ) ) ;
}
 
/**
* Override the draw function of the list
* Otherwise it will apply a default background instead of transparent
* On s60 3rd mr, there will be bugs when the list is large than default. ( A ugly white bar at the end of list)
*/

void CFishEyeListBox::Draw ( const TRect& aRect) const {
CListBoxView* view = View( ) ;
TInt start = view->TopItemIndex( ) ;
TInt end = view->BottomItemIndex( ) ;
for ( TInt i = start; i <= end; i++ ) {
view->DrawItem( i) ;
}
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值