我在absolutelayout中有一个框架,如下所示。我希望该用户能够在屏幕上拖动和重新定位此框架。我试图实现一个平移手势但不幸的是它没有按预期工作。我可以向我展示正确的方法吗?是否可以不使用任何第三方库?
<AbsoluteLayout>
<Frame x:Name="frm" Padding="1" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0.5,0,0.3,0.3" IsVisible="{Binding IsSmallTimerVisible}" >
<Frame.GestureRecognizers>
<PanGestureRecognizer PanUpdated="OnPanUpdated" />
</Frame.GestureRecognizers>
<shared:_customControl/>
</Frame>
Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<Grid.RowDefinitions>
<RowDefinition Height="0.1*" />
<RowDefinition Height="0.3*" />
<RowDefinition Height="2.5*" />
</Grid.RowDefinitions>
在
背后的代码中 double x, y;
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
switch (e.StatusType)
{
case GestureStatus.Running:
// Translate and ensure we don't pan beyond the wrapped user interface element bounds.
Content.TranslationX =
Math.Max(Math.Min(0, x + e.TotalX), -Math.Abs(Content.Width - App.ScreenWidth));
Content.TranslationY =
Math.Max(Math.Min(0, y + e.TotalY), -Math.Abs(Content.Height - App.ScreenHeight));
break;
case GestureStatus.Completed:
{
// Store the translation applied during the pan
x = Content.TranslationX;
y = Content.TranslationY;
AbsoluteLayout.SetLayoutBounds(frm, new Rectangle(x, y, .3, .3));
break;
}
}
}
答案 0 :(得分:1)
看起来像你需要的是触摸跟踪效果
This示例与您的要求非常相似。
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
BoxView boxView = sender as BoxView;
switch (args.Type)
{
case TouchActionType.Pressed:
// Don't allow a second touch on an already touched BoxView
if (!dragDictionary.ContainsKey(boxView))
{
dragDictionary.Add(boxView, new DragInfo(args.Id, args.Location));
// Set Capture property to true
TouchEffect touchEffect = (TouchEffect)boxView.Effects.FirstOrDefault(e => e is TouchEffect);
touchEffect.Capture = true;
}
break;
case TouchActionType.Moved:
if (dragDictionary.ContainsKey(boxView) && dragDictionary[boxView].Id == args.Id)
{
Rectangle rect = AbsoluteLayout.GetLayoutBounds(boxView);
Point initialLocation = dragDictionary[boxView].PressPoint;
rect.X += args.Location.X - initialLocation.X;
rect.Y += args.Location.Y - initialLocation.Y;
AbsoluteLayout.SetLayoutBounds(boxView, rect);
}
break;
case TouchActionType.Released:
if (dragDictionary.ContainsKey(boxView) && dragDictionary[boxView].Id == args.Id)
{
dragDictionary.Remove(boxView);
}
break;
}
}
Pressed逻辑设置TouchEffect对象的Capture属性 为真。这具有为所有后续事件提供的效果 那个手指指向同一个事件处理程序。
Moved逻辑通过更改LayoutBounds来移动BoxView 附属财产。事件参数的Location属性是 总是相对于被拖动的BoxView,如果BoxView是 以恒定速率拖动,位置属性 连续的事件将大致相同。例如,如果是 手指在其中心按下BoxView,Pressed动作存储了一个 PressPoint属性(50,50),后续保持不变 事件。如果BoxView以恒定速率对角拖动,则 Moved操作期间的后续位置属性可能是值 (55,55),在这种情况下,Moved逻辑将水平加5 和BoxView的垂直位置。这会移动BoxView 它的中心再次直接在手指下。
您可以使用不同的方式同时移动多个BoxView元素 手指。