我有一个简单的Xamarin.Forms页面,其中的网格布局位于BoxViews内部。我希望能够通过滑动手势同时选择这些框视图。我该如何实现?
我想构建一种平铺地图,以便更轻松地选择Boxview。我想轻松实现这一目标。仅刷卡效果不佳,因为只会选择“一个”框视图。
这是我到目前为止所拥有的:
XAML
<ContentPage.Content>
<Grid x:Name="pageGrid" RowSpacing="1" ColumnSpacing="1" VerticalOptions="Center" HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
</ContentPage.Content>
后面的代码:
public Page()
{
InitializeComponent();
int columnIndex = 0;
for (int rowIndex = 0; rowIndex <= 8; rowIndex++)
{
BoxView boxview = new BoxView { BackgroundColor = Color.White };
SwipeGestureRecognizer swipeGestureRecognizer = new SwipeGestureRecognizer();
swipeGestureRecognizer.Swiped += (sender, args) =>
{
if (boxview.BackgroundColor == Color.White)
{
boxview.BackgroundColor = Color.Gray;
}
else if (boxview.BackgroundColor == Color.Gray)
{
boxview.BackgroundColor = Color.White;
}
};
swipeGestureRecognizer.Threshold = 1;
swipeGestureRecognizer.Direction = SwipeDirection.Left | SwipeDirection.Right;
TapGestureRecognizer tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (sender, args) =>
{
if (boxview.BackgroundColor == Color.White)
{
boxview.BackgroundColor = Color.Gray;
}
else if (boxview.BackgroundColor == Color.Gray)
{
boxview.BackgroundColor = Color.White;
}
};
boxview.GestureRecognizers.Add(swipeGestureRecognizer);
boxview.GestureRecognizers.Add(tapGestureRecognizer);
if (rowIndex == 4 && columnIndex == 3)
{
boxview.BackgroundColor = Color.Red;
}
pageGrid.Children.Add(boxview, columnIndex, rowIndex);
if (rowIndex != 8) continue;
if (columnIndex == 6) return;
columnIndex += 1;
rowIndex = -1;
}
}
现在,每项滑动操作都只会选择一个框视图!
答案 0 :(得分:0)
我对此进行了一些尝试,并提出了一些想法,这些想法将在随后的部分实现中实现。
我认为滑动手势不会像我认为那样使它起作用。看起来Swipe手势正好触发一次,从屏幕上抬起手指时,这对我来说不是理想的体验,因为这意味着即使您可以算出总共滑过哪些框(我'不确定是否可以这样做),他们都会等到您抬起手指来改变颜色。
我刚想到的想法是使用平移手势,因为一旦检测到运动,就会非常频繁地触发。平移和滑动似乎都具有这样的约束条件:一旦事件与单个BoxView相关联,即使手指移过其他框,该事件也不会触发其他任何回调。但是,我认为使用平移手势可以解决此问题。平移手势会为您提供每次触发时的总平移偏差,并且鉴于手势回调本身会在平移开始的Boxview内部(而不是在其他任何框内)持续触发,这意味着您既有初始位置又有每个平移运动的总偏差。从理论上讲,您拥有完成此工作所需的所有信息,但是您需要对事件进行一些智能处理。可能会让人头疼,但是如果您可以构建自己的网格,那么足够聪明地知道每个BoxView与其他BoxView的关系,则可以在它们进入时绘制出平移手势事件,并根据需要更改特定BoxView的颜色。
编辑:应询问者的要求,我建立了一些示例代码来执行此操作。有必要重新添加单个敲击事件,并使其正确地“切换”,而不是仅根据所需的逻辑进行选择。可能还需要进行其他调整,但这证明了这一概念。
public Page()
{
InitializeComponent();
var columnIndex = 0;
for (var rowIndex = 0; rowIndex <= 8; rowIndex++)
{
var boxview = new BoxView { BackgroundColor = Color.White };
var swipeGestureRecognizer = new PanGestureRecognizer();
swipeGestureRecognizer.PanUpdated += (sender, args) =>
{
var boxView = (BoxView) sender;
var panBaseBounds = boxView.Bounds;
var eventX = panBaseBounds.X + args.TotalX;
var eventY = panBaseBounds.Y + args.TotalY;
foreach (var gridChild in pageGrid.Children)
{
var testBounds = gridChild.Bounds;
if (testBounds.X <= eventX && eventX <= testBounds.X + testBounds.Width &&
testBounds.Y <= eventY && eventY <= testBounds.Y + testBounds.Height)
{
gridChild.BackgroundColor = Color.Gray;
break;
}
}
};
boxview.GestureRecognizers.Add(swipeGestureRecognizer);
if (rowIndex == 4 && columnIndex == 3)
{
boxview.BackgroundColor = Color.Red;
}
pageGrid.Children.Add(boxview, columnIndex, rowIndex);
if (rowIndex != 8) continue;
if (columnIndex == 6) return;
columnIndex += 1;
rowIndex = -1;
}
}