S60:symbian 自定义TabGroup [转]

一直没有时间来总结工作中学到的东西,也在一直想做一个自己的自定义控件库。也许是有点懒的缘故,但是真正当自己需要用这些东西的时候又要到处去寻找答案,去搜寻自己所做的项目的时候却发现还是把一下小小的零件拆下来,就不必去搜索偌大的一个项目,不必去google网上一些琐碎的记忆。有时候真会起到一种事半功倍的效果。那就让我们来珍惜时间去学习更多的东西吧。
当您觉得系统自带的TabGroup无法满足您的要求时,当您的上司需要您做个很炫的TabGroup来增加产品的吸引力,满足用户体验时,不妨试下下面的TabGroup,会让您的作品有一种焕然一新的感觉,下面就让我带着您来体验一下自定义TabGroup的全方位好处吧。

控件头文件(TabControls.h)
#ifndef TABCONTROLS_H
#define TABCONTROLS_H
// INCLUDES
#include <e32std.h>
#include <e32base.h>
#include <coecntrl.h>
#include <AknsDrawUtils.h> // skin
#include <AknsBasicBackgroundControlContext.h> //skin
// CLASS DECLARATION
class CGulIcon;
class CTabControls : public CCoeControl
{
public://析构函数和二阶段静态构造函数
~CTabControls();
static CTabControls* NewL(const TRect& aRect,const CCoeControl* aParent);
static CTabControls* NewLC(const TRect& aRect,const CCoeControl* aParent);
private://构造函数和ConstructL方法
CTabControls(const TRect& aRect);
void ConstructL(const TRect& aRect,const CCoeControl* aParent);
public://响应按钮事件
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
protected://控件大小和位置设置
void SizeChanged();
private://绘制控件及控件区域
void Draw(const TRect& aRect) const;
public:
void SetIconArray(CArrayPtr<CGulIcon>* aIconArray,TInt aTabImageSize); //设置图标
void SetTitleAndTabBackgroundSize(TInt aTitleSize,TInt aTabBackgroundSize); //设置标题和TAB背景大小
void SetTabTitleArray(CDesCArrayFlat* aTabTitleArray); //设置标签页
TInt GetActiveTabIndex(); //获取当前活动的标签
private:
TRect iRect;
TInt iActiveTabIndex; // 当前活动的标签
CArrayPtr<CGulIcon>* iIconArray; //图标数组
CDesCArrayFlat* iTabTitleArray; //标题数组
TBuf<16> iTitle; //程序标题
TInt iNumberOfTabsToBeShown; //tab个数
TInt iTabImageSize; //tab图片大小
TInt iTitleSize; // 程序标题大小
TInt iTabBackgroundSize; //tab背景宽度 或者叫高度
};
#endif // TABCONTROLS_H

控件源文件(TabControls.cpp)
#include <gulicon.h>
#include <eikenv.h>
#include <AknAppUi.h>
#include <AknUtils.h>
#include "TabControls.h"
_LIT(KSuccess3,"UCWEB"); //刚进去默认主页
_LIT(KSuccess2,"\x9875\x9762\x4E8C"); //页面2
_LIT(KSuccess1,"\x9875\x9762\x4E00"); //页面1
_LIT(KSuccess4,"\x9875\x9762\x56DB"); //页面4
_LIT(KSuccess5,"\x9875\x9762\x4E94"); //页面5
CTabControls::CTabControls(const TRect& aRect):iRect(aRect)
{
iNumberOfTabsToBeShown = 5;
iTabImageSize = 0;
iActiveTabIndex = 3;
iTitleSize = 30;
iTabBackgroundSize = 50;
}
CTabControls::~CTabControls()
{
if(iIconArray)
{
delete iIconArray;
iIconArray = NULL;
// iIconArray->ResetAndDestroy();
}
if(iTabTitleArray)
{
iTabTitleArray->Reset();
}
}
CTabControls* CTabControls::NewLC(const TRect& aRect,const CCoeControl* aParent)
{
CTabControls* self = new (ELeave) CTabControls(aRect);
CleanupStack::PushL(self);
self->ConstructL(aRect,aParent);
return self;
}
CTabControls* CTabControls::NewL(const TRect& aRect,const CCoeControl* aParent)
{
CTabControls* self = CTabControls::NewLC(aRect,aParent);
CleanupStack::Pop(); // self;
return self;
}
void CTabControls::ConstructL(const TRect& aRect,const CCoeControl* aParent)
{
iIconArray = NULL;
iTabTitleArray = NULL;
if(aParent == NULL)
{
CreateWindowL();
iAvkonAppUi->AddToStackL(this);
}
else
{
// Part of a compound control, so just share
// the parent's window
SetContainerWindowL(*aParent);
}

SetRect(aRect);
ActivateL();
}
void CTabControls::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
gc.Clear(aRect);
TInt aHeight = 0;
TInt aWidth = 0;
aHeight = aRect.Height();
aWidth = aRect.Width();

//画线代替渐变效果 画线效率高
TInt aStartColor = 66; //x是开始颜色的 3个值 比如 TRgb startColor(56,56,56); //开始颜色
TInt aEndColor = 1; //y是结束颜色的3个值 TRgb endColor(1,1,1); //结束颜色
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(2,2));
TInt j = 0;
while(j < iTitleSize)
{
gc.SetPenColor(TRgb(aStartColor--,aStartColor--,aStartColor--));
gc.DrawLine(TPoint(0,j),TPoint(aWidth,j));
j = j+2;
}
//画下面的TAB背景
TRect aRectBackground(TPoint(0,iTitleSize),TPoint(aWidth,iTitleSize+iTabBackgroundSize));
TRgb KTabBackgroundColor(222,226,229);
gc.SetPenColor (KTabBackgroundColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.SetBrushColor(KTabBackgroundColor);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRectBackground);
//创建字体 在切换TAB页的时候变换标题上的字
const CFont* myfont = NULL;
myfont=CEikonEnv::Static()->TitleFont();
gc.UseFont(myfont);
//CFont* myfont = const_cast<CFont*> (ApacPlain12());
//CFont *TimeFont2 = NULL;
//TFontSpec tFontSpec2 = myfont->FontSpecInTwips();
//tFontSpec2.iFontStyle.SetStrokeWeight(EStrokeWeightBold);//修改是否加粗
//tFontSpec2.iHeight *= 2 ;//修改大小
//iCoeEnv->ScreenDevice()->GetNearestFontInTwips(TimeFont2 , tFontSpec2);
//gc.UseFont( TimeFont2 );
//画选中的状态
TInt tabWidth=aWidth/iNumberOfTabsToBeShown; //每个tab的宽度
TRgb KTabSelectedColor(142,163,184);
gc.SetPenColor (KTabSelectedColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.SetBrushColor(KTabSelectedColor);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
switch(iActiveTabIndex)
{
case 1:
{
//选中矩形框的位置
TRect aRectTabSelected(TPoint(((tabWidth-iTabImageSize)/4),iTitleSize+3),
TPoint(tabWidth-((tabWidth-iTabImageSize)/4),iTabBackgroundSize*2-iTabImageSize/2));
gc.DrawRoundRect(aRectTabSelected,TSize(3,3));
//画程序标题上的字
TRgb KfontColor(242,242,242);
gc.SetPenColor(KfontColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.DrawText(KSuccess1,TPoint(4,iTitleSize-iTitleSize/8)); //字的位置在标题框的做上角中间
}
break;
case 2:
{
TRect aRectTabSelected(TPoint(((tabWidth-iTabImageSize)/4)+tabWidth,iTitleSize+3),
TPoint(tabWidth*2-((tabWidth-iTabImageSize)/4),iTabBackgroundSize*2-iTabImageSize/2));
gc.DrawRoundRect(aRectTabSelected,TSize(3,3));
//画程序标题上的字
TRgb KfontColor(242,242,242);
gc.SetPenColor (KfontColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.DrawText(KSuccess2,TPoint(4,iTitleSize-iTitleSize/8));
}
break;
case 3:
{
TRect aRectTabSelected(TPoint(((tabWidth-iTabImageSize)/4)+tabWidth*2,iTitleSize+3),
TPoint(tabWidth*3-((tabWidth-iTabImageSize)/4),iTabBackgroundSize*2-iTabImageSize/2));
gc.DrawRoundRect(aRectTabSelected,TSize(3,3));
//画程序标题上的字
TRgb KfontColor(242,242,242);
gc.SetPenColor (KfontColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.DrawText(KSuccess3,TPoint(4,iTitleSize-iTitleSize/8));
}
break;
case 4:
{
TRect aRectTabSelected(TPoint(((tabWidth-iTabImageSize)/4)+tabWidth*3,iTitleSize+3),
TPoint(tabWidth*4-((tabWidth-iTabImageSize)/4),iTabBackgroundSize*2-iTabImageSize/2));
gc.DrawRoundRect(aRectTabSelected,TSize(3,3));
//画程序标题上的字
TRgb KfontColor(242,242,242);
gc.SetPenColor (KfontColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.DrawText(KSuccess4,TPoint(4,iTitleSize-iTitleSize/8));
}
break;
case 5:
{
TRect aRectTabSelected(TPoint(((tabWidth-iTabImageSize)/4)+tabWidth*4,iTitleSize+3),
TPoint(tabWidth*5-((tabWidth-iTabImageSize)/4),iTabBackgroundSize*2-iTabImageSize/2));
gc.DrawRoundRect(aRectTabSelected,TSize(3,3));
//画程序标题上的字
TRgb KfontColor(242,242,242);
gc.SetPenColor (KfontColor);
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenSize(TSize(1,1));
gc.DrawText(KSuccess5,TPoint(4,iTitleSize-iTitleSize/8));
}
break;
default:
break;
}
//释放字体
gc.DiscardFont();
// gc.Device()->ReleaseFont(TimeFont2);
gc.SetBrushStyle(CGraphicsContext::ENullBrush);
gc.SetPenStyle(CGraphicsContext::ENullPen);
//画tab图片
TSize tabSize(tabWidth,aRect.Height());
TRect tabRect(tabSize);
tabRect.iTl.iX+=(tabWidth-iTabImageSize)/2; //x代表 横的左边
tabRect.iBr.iX+=(tabWidth-iTabImageSize)/2;
//宽度减去图片的宽度。KTitleSize 是黑标题的宽度 KTabBackgroundSize是白色的背景的 宽度
tabRect.iTl.iY+=iTitleSize+(iTabBackgroundSize-iTabImageSize)/2;
tabRect.iBr.iY+=iTitleSize+(iTabBackgroundSize-iTabImageSize)/2; //y代表竖的坐标
for(TInt i=0;i<iNumberOfTabsToBeShown;i++)
{
CFbsBitmap* tab=NULL;
CGulIcon* icon=NULL;
if(i<iIconArray->Count())
icon = iIconArray->At(i);
if(icon)
tab = icon->Bitmap();
if(tab)
{
TRect rect;
rect.iTl.iX=0;
rect.iTl.iY=0;
rect.iBr.iX=tabRect.Width();
rect.iBr.iY=tabRect.Height();
gc.BitBltMasked(tabRect.iTl,tab,rect,icon->Mask(),EFalse);
}
tabRect.iTl.iX+=tabWidth; // 每画一个图片,坐标想有移动 一个tab宽度
tabRect.iBr.iX+=tabWidth;
}
}

TKeyResponse CTabControls::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
TKeyResponse ret=EKeyWasNotConsumed;
// if(IsFocused() && EEventKeyUp == aType)
// {
switch (aKeyEvent.iScanCode)
{
case EStdKeyLeftArrow:
{
if(iActiveTabIndex>1)
iActiveTabIndex--;
else
iActiveTabIndex=iIconArray->Count();
DrawNow();
ret=EKeyWasConsumed;
}
break;
case EStdKeyRightArrow:
{
if(iActiveTabIndex<iIconArray->Count())
iActiveTabIndex++;
else
iActiveTabIndex=1;
DrawNow();
ret=EKeyWasConsumed;
}
break;
default:
break;
}
//}
return ret;
}
void CTabControls::SetIconArray(CArrayPtr<CGulIcon>*aIconArray,TInt aTabImageSize) // 设置图标
{
if(iIconArray != NULL)
{
iIconArray->ResetAndDestroy();
}
iIconArray=aIconArray;
iTabImageSize = aTabImageSize;
}
void CTabControls::SetTabTitleArray(CDesCArrayFlat* aTabTitleArray)// 设置标题
{
if(iTabTitleArray != NULL)
{
iTabTitleArray->Reset();
}
iTabTitleArray=aTabTitleArray;
}
TInt CTabControls::GetActiveTabIndex()
{
return iActiveTabIndex;
}
void CTabControls::SizeChanged()
{
DrawNow();
}

void CTabControls::SetTitleAndTabBackgroundSize(TInt aTitleSize,TInt aTabBackgroundSize) //设置标题 背景大小
{
iTitleSize = aTitleSize;
iTabBackgroundSize = aTabBackgroundSize;
}

用法(我用的svg图面,bmp请稍微改动)
//TAB 控件
iCTabControls = CTabControls::NewL(aRect,this);
CArrayPtr< CGulIcon >* aTabiconArray = NULL;
aTabiconArray = new (ELeave) CAknIconArray(5);
CleanupStack::PushL( aTabiconArray );
CFbsBitmap* aBmp1 = NULL;
CFbsBitmap* aBmp2 = NULL;
CFbsBitmap* aBmp3 = NULL;
CFbsBitmap* aBmp4 = NULL;
CFbsBitmap* aBmp5 = NULL;
CFbsBitmap* aBmpMask1 = NULL;
CFbsBitmap* aBmpMask2 = NULL;
CFbsBitmap* aBmpMask3 = NULL;
CFbsBitmap* aBmpMask4 = NULL;
CFbsBitmap* aBmpMask5 = NULL;
CGulIcon* aIcon1 = NULL;
CGulIcon* aIcon2 = NULL;
CGulIcon* aIcon3 = NULL;
CGulIcon* aIcon4 = NULL;
CGulIcon* aIcon5 = NULL;
AknIconUtils::CreateIconLC(aBmp1, aBmpMask1, KTabsFileName,
EMbmTabdraw_aifTab1,EMbmTabdraw_aifTab1_mask);
AknIconUtils::SetSize(aBmp1, TSize(40,40), EAspectRatioPreserved);
AknIconUtils::SetSize(aBmpMask1, TSize(40,40), EAspectRatioPreserved);
aIcon1 = CGulIcon::NewL(aBmp1, aBmpMask1);
CleanupStack::Pop (2); // aBmp1 aBmpMask1
CleanupStack::PushL(aIcon1);
aTabiconArray->AppendL(aIcon1);
CleanupStack::Pop (aIcon1);
AknIconUtils::CreateIconLC(aBmp2, aBmpMask2, KTabsFileName,
EMbmTabdraw_aifTab2,EMbmTabdraw_aifTab2_mask);
AknIconUtils::SetSize(aBmp2, TSize(40,40), EAspectRatioNotPreserved);
AknIconUtils::SetSize(aBmpMask2, TSize(40,40), EAspectRatioNotPreserved);
aIcon2 = CGulIcon::NewL(aBmp2, aBmpMask2);
CleanupStack::Pop (2); // aBmp2 aBmpMask2
CleanupStack::PushL(aIcon2);
aTabiconArray->AppendL(aIcon2);
CleanupStack::Pop(aIcon2);
AknIconUtils::CreateIconLC(aBmp3, aBmpMask3, KTabsFileName,
EMbmTabdraw_aifTab3,EMbmTabdraw_aifTab3_mask);
AknIconUtils::SetSize(aBmp3, TSize(40,40), EAspectRatioNotPreserved);
AknIconUtils::SetSize(aBmpMask3, TSize(40,40), EAspectRatioNotPreserved);
aIcon3 = CGulIcon::NewL(aBmp3, aBmpMask3);
CleanupStack::Pop (2); // aBmp3 aBmpMask3
CleanupStack::PushL(aIcon3);
aTabiconArray->AppendL(aIcon3);
CleanupStack::Pop(aIcon3);
AknIconUtils::CreateIconLC(aBmp4, aBmpMask4, KTabsFileName,
EMbmTabdraw_aifTab4,EMbmTabdraw_aifTab4_mask);
AknIconUtils::SetSize(aBmp4, TSize(40,40), EAspectRatioNotPreserved);
AknIconUtils::SetSize(aBmp4, TSize(40,40), EAspectRatioNotPreserved);
aIcon4 = CGulIcon::NewL(aBmp4, aBmpMask4);
CleanupStack::Pop (2); // aBmp4 aBmpMask4
CleanupStack::PushL(aIcon4);
aTabiconArray->AppendL(aIcon4);
CleanupStack::Pop(aIcon4);
AknIconUtils::CreateIconLC(aBmp5, aBmpMask5, KTabsFileName,
EMbmTabdraw_aifTab5,EMbmTabdraw_aifTab5_mask);
AknIconUtils::SetSize(aBmp5, TSize(40,40), EAspectRatioNotPreserved);
AknIconUtils::SetSize(aBmpMask5, TSize(40,40), EAspectRatioNotPreserved);
aIcon5 = CGulIcon::NewL(aBmp5, aBmpMask5);
CleanupStack::Pop (2); // aBmp5 aBmpMask5
CleanupStack::PushL(aIcon5);
aTabiconArray->AppendL(aIcon5);
CleanupStack::Pop(aIcon5);
iCTabControls->SetIconArray(aTabiconArray,40);
CleanupStack::Pop( aTabiconArray );
iCTabControls->SetTitleAndTabBackgroundSize(30,50);//设定标题大小,tab背景宽度
界面效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值