18.3.OrangeUI控件使用说明(图片列表查看控件ImageListViewer)(示例3 解决与滚动控件的手势冲突)

通常,我们会在App首页的滚动控件上放一个ImageListViewer,

滚动控件可以是ScollBox,ListBox或ListView,

它们都具有上下滑动的功能,

而ImageListViewer具有左右切换图片的功能,

这样一来,当我在ImageListViewer左右切换图片时,

很容易造成滚动控件的上下滑动,

十分影响用户体验,

 

正确的效果应该是,

我在ImageListViewer上垂直切换时滚动控件才会上下滑动,

其他情况下,ImageListViewer都应该能切换图片,

 

如何解决这种手势冲突呢?

 

所有滚动控件都是从ScrollControl继承的,

ScrollControl有两个手势管理组件,

VertControlGestureManager和HorzControlGestureManager,

VertControlGestureManager用来处理上下滑动,上下惯性滚动等,

我们需要把VertControlGestureManager.IsNeedDecideFirstGestureKind设置为True,

IsNeedDecideFirstGestureKind为True了之后,

表示每次开始手势滑动ScrollControl时,都需要先滑动一段距离,

然后VertControlGestureManager判断出滑动的方向为上下垂直方向之后,

才响应上下滚动,

当ScrollControl上面放了ImageListViewer之后,

只需要手势滑动在ImageListViewer上时需要判断上下垂直方向,

在ImageListViewer之外的地方则不需要判断,

如下箭头所示:

那就要编写VertControlGestureManager.OnPrepareDecidedFirstGestureKind事件,

这个事件会传入鼠标滑动所在的位置,

如果鼠标滑动位置在ImageListViewer中,

那么需要判断上下垂直方向,

如果不在ImageListViewer中,那么不需要判断方向,

ScrollBox处理的代码如下:

procedure TFrameHome.DoScrollBoxVertManagerPrepareDecidedFirstGestureKind(

Sender: TObject; AMouseMoveX, AMouseMoveY: Double;

var AIsDecidedFirstGestureKind: Boolean;

var ADecidedFirstGestureKind: TGestureKind);

var

APlayerOriginPoint:TPointF;

AFirstItemRect:TRectF;

begin

//传给ScrollBox的是相对窗体的绝对坐标

//广告轮播Item的绘制区域

APlayerOriginPoint:=PointF(0,0);

APlayerOriginPoint:=imgPlayer.LocalToAbsolute(APlayerOriginPoint);

AFirstItemRect:=RectF(APlayerOriginPoint.X,APlayerOriginPoint.Y,

APlayerOriginPoint.X+Self.imgPlayer.Width,

APlayerOriginPoint.Y+Self.imgPlayer.Height

);

if PtInRect(AFirstItemRect,PointF(AMouseMoveX,AMouseMoveY)) then

begin

//在广告轮播控件内,那么要检查初始手势方向

end

else

begin

//不在在广告轮播控件内,那么随意滑动

//AIsDecidedFirstGestureKind表示我已经确定好方向了,不需要再判断了

//ADecidedFirstGestureKind表示判断好的方向

AIsDecidedFirstGestureKind:=True;

ADecidedFirstGestureKind:=TGestureKind.gmkVertical;

end;

end;

 

初始设置代码如下:

Self.sbClient.Prop.VertControlGestureManager.IsNeedDecideFirstGestureKind:=True;

Self.sbClient.Prop.VertControlGestureManager.OnPrepareDecidedFirstGestureKind:=

Self.DoScrollBoxVertManagerPrepareDecidedFirstGestureKind;

 

 

ListBox处理的代码如下:

procedure TFrameShop.DoListBoxVertManagerPrepareDecidedFirstGestureKind(

Sender: TObject; AMouseMoveX, AMouseMoveY: Double;

var AIsDecidedFirstGestureKind: Boolean;

var ADecidedFirstGestureKind: TGestureKind);

var

AFirstItemRect:TRectF;

begin

//广告轮播Item的绘制区域

AFirstItemRect:=Self.lbHome.Prop.Items[0].ItemDrawRect;

if PtInRect(AFirstItemRect,PointF(AMouseMoveX,AMouseMoveY)) then

begin

//在广告轮播控件内,那么要检查初始手势方向

end

else

begin

//不在在广告轮播控件内,那么随意滑动

AIsDecidedFirstGestureKind:=True;

ADecidedFirstGestureKind:=TGestureKind.gmkVertical;

end;

end;

 

初始设置代码如下:

Self.lbHome.Prop.VertControlGestureManager.IsNeedDecideFirstGestureKind:=True;

Self.lbHome.Prop.VertControlGestureManager.OnPrepareDecidedFirstGestureKind:=

Self.DoListBoxVertManagerPrepareDecidedFirstGestureKind;

 

 

 

发表评论