Как воспроизвести анимацию, когда элемент выбран в CollectionView?

#xamarin.forms

#xamarin.forms

Вопрос:

У меня есть следующий CollectionView:

 <CollectionView ItemsSource="{Binding Brands}" Margin="5, 0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
  <CollectionView.ItemTemplate>
    <DataTemplate>
      <pv:PancakeView Margin="0,0,0,10" Padding="10" CornerRadius="45">
        <pv:PancakeView.GestureRecognizers>
          <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
        </pv:PancakeView.GestureRecognizers>

        <pv:PancakeView.BackgroundGradientStops>
          <pv:GradientStopCollection>
            <pv:GradientStop Color="#4166f5" Offset="0.0" />
            <pv:GradientStop Color="#1e90ff" Offset="1.0" />
          </pv:GradientStopCollection>
        </pv:PancakeView.BackgroundGradientStops>

        <Frame Padding="0" IsClippedToBounds="True" HorizontalOptions="Center" VerticalOptions="Center"
          CornerRadius="45">
          <ff:CachedImage Source="{Binding image}" Aspect="AspectFill" />
        </Frame>
      </pv:PancakeView>
    </DataTemplate>
  </CollectionView.ItemTemplate>
</CollectionView>
  

Я решил, что анимация выбранного элемента будет классной, поэтому я добавил TapGestureRecognizer .
Событие, на которое оно указывает, просто масштабирует PancakeView вниз, а затем масштабирует его.

После завершения я связал SelectedItem и SelectionChangedCommand из CollectionView

 SelectedItem="{Binding SelectedBrand}" SelectionChangedCommand="{Binding BrandSelected}"
                        SelectionMode="Single"
  

Затем я понял, что TapGestureRecognizer блокирует событие нажатия CollectionView.

Как я могу анимировать PancakeView выбранного элемента, не блокируя команду SelectionChangedCommand ?

Ответ №1:

Поскольку вы использовали MVVM, вы могли напрямую обрабатывать логику в ViewModel .

1. Определите подкласс PancakeView

 public class MyPancakeView: PancakeView
{

    public static BindableProperty IndexProperty =
       BindableProperty.Create(nameof(Index), typeof(int), typeof(PancakeView));

    public int Index
    {
        get => (int)GetValue(IndexProperty);
        set => SetValue(IndexProperty, value);
    }

    public MyPancakeView()
    {
        MessagingCenter.Subscribe<Object, int>(this,"tap",(org,id)=> { 
        
            if(id==this.Index)
            {
                // set  animation here
            }


        });
    }


}
  

2. Добавьте идентификатор свойства в свою модель ItemsSource .

 public class YourModel
{
   public int Id {get;set;}
   
  // other properties
}

And set it as the index of ItemSource (0,1,2...)

  

3. В xaml

 <local:MyPancakeView Index="{Binding Id}" > 
 
   //...
  
</local:MyPancakeView>
  

4. в ViewModel

в методе set SelectedBrand

   public YourModel SelectedBrand
    {
        get
        {
            return xxx;
        }

        set
        {
            if(value!=xxx)
            {
                xxx = value;
                OnPropertyChanged("SelectedBrand");
                MessagingCenter.Send<Object, int>(this,"tap", SelectedBrand.Id);
            }
        }
    }