2

我对原生 Symbian 组件的实现程度感到惊讶。其中之一是 CAknSlider。CAknSlider 是一个控件,它有一个滑块,用户可以使用它沿着一个方向可以是垂直或水平的条形滑动它。

现在,当您滑动滑块时,滑动非常顺畅,不会闪烁。但是如果由于某种原因我要实现一个自定义滑块控件,我就不会像 CAknSlider 那样整洁。

所以我的问题是如何弄清楚 CAknSlider 是如何在幕后实现的。我想为我的收音机应用程序实现一个自定义滑块来控制音频流的音量。

知道我应该怎么做。


[编辑:回应laalto的评论]

CAknSlider 控件通常作为设置屏幕中的设置项来实现。

我从未见过它在复合控件容器(如 CCoeControl 或 CAknView )中实现为组件控件。这是我到目前为止所尝试的:

首先,我创建了一个描述滑块控件的资源文件,如下所示:

RESOURCE SLIDER r_volume_slider
{
 layout=EAknCtSlider;
 minvalue=0;
 maxvalue=10;
 step=1;
 valuetype=EAknSliderValuePercentage;
 minlabel="mute";
 maxlabel="full";
}

然后我使用源文件中的资源文件来创建滑块,如下所示:

void CVolumePopupAppView::ConstructL(const TRect& aRect)
{
// Create a window for this application view
CreateWindowL();

InitComponentArrayL( );
iSlider = new ( ELeave ) CAknSlider( );
TResourceReader reader;
iEikonEnv->CreateResourceReaderLC( reader, R_VOLUME_SLIDER );

iSlider->ConstructFromResourceL( reader );
CleanupStack::PopAndDestroy ( );
iSlider->SetContainerWindowL( *this );
iSlider->SetParent( this );

Components().AppendLC( iSlider );

CleanupStack::Pop ( iSlider );

// Set the windows size
SetRect(aRect);

// Activate the window, which makes it ready to be drawn
ActivateL();
}

现在这里是作为设置项的 CAknSlider ( Screenshot1 ) 和通过上述技术创建的 CAknSlider ( Screenshot2 ) 之间的比较。请注意,我创建的那个没有百分比值指示符以及最小和最大文本标签,即使我在资源中指定了它们。外观和感觉也很可悲。

4

2 回答 2

2

有很多技术可以避免闪烁,从双缓冲整个屏幕到更简单的优化,比如只重新绘制控件中实际发生变化的部分。预先绘制适当的矩形以覆盖滑块所在的位置及其下一步可能是有效执行此操作的最简单方法。

要确切了解 CAknSlider 是如何做到的,您可以:1) 等待 Symbian Foundation 平台中的相关软件包开源 (EPL) - 应该在未来 12 个月内的某个时间,或 2) 加入 Symbian Foundation 并获得立即访问源代码

编辑:(应要求提供有关图形优化的更多详细信息)

最常见的闪烁是由重绘整个控件引起的。我已经(通过移植项目)实现了一些不会在此处闪烁的自定义控件:http://developer.symbian.com/main/documentation/porting/#linux2 甚至还有一些有点像滑块的东西。这个例子远非理想,它没有预先绘制的矩形,但图形是非常简单的线条和填充的矩形。不过,仅覆盖更改部分的概念是相同的。对预先绘制的部分进行 blit。将滑块的背景绘制到屏幕外位图上,并对滑块的可移动部分执行相同操作。当滑块移动时,通过从屏幕外背景(仅需要擦除的部分)执行 BitBlt() 擦除可移动部分,然后将可移动部分 BitBlt() 移动到新位置。

那有意义吗?

于 2009-05-29T07:19:28.467 回答
1

你需要CAknSlider吗?偷它!:) CAknSliderSettingPage 为我们做一切。我们,就用那个。

iSettingPage = new(ELeave) CAknSliderSettingPage(R_SLIDER_PAGE, iValue);
iSettingPage->ConstructL();

iSettingPage->SetSize(iSettingPage->MinimumSize());

TInt CCustomColorPalette::CountComponentControls() const
{
    return 1;
}

CCoeControl* CCustomColorPalette::ComponentControl( TInt aIndex ) const
{
   return iSettingPage->SliderControl();
}
于 2009-06-01T20:43:09.653 回答