如何改进 ListViewBase 动画?
How can a ListViewBase animation be improved?
我正在创建一个基于合成的动画,我想在加载每个 ListViewItem 时对其进行缩放。我有以下示例代码:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
MyList.ContainerContentChanging += (sender, args) =>
{
if (!args.InRecycleQueue)
{
args.ItemContainer.Loaded += (item, e) =>
{
var lvi = item as ListViewItem;
var panel = FindDescendant<ItemsStackPanel>(MyList);
var visual = ElementCompositionPreview.GetElementVisual(lvi);
var index = MyList.IndexFromContainer(lvi);
if (index >= panel.FirstVisibleIndex && index <= panel.LastVisibleIndex)
{
var width = (float)lvi.RenderSize.Width;
var height = (float)lvi.RenderSize.Height;
visual.CenterPoint = new Vector3(width / 2, height / 2, 0f);
var zoom = visual.Compositor.CreateVector3KeyFrameAnimation();
zoom.Duration = TimeSpan.FromSeconds(2);
zoom.DelayTime = TimeSpan.FromMilliseconds(index * 100);
zoom.InsertKeyFrame(0.0f, new Vector3(0.75f, 0.75f, 0f));
zoom.InsertKeyFrame(1.0f, new Vector3(1.0f, 1.0f, 0f));
visual.StartAnimation("Scale", zoom);
}
};
}
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var col = new List<int>();
for (var x = 0; x < 200; x++)
{
var z = new Random();
col.Add(z.Next(0, 1000));
}
MyList.ItemsSource = null;
MyList.ItemsSource = col;
}
private T FindDescendant<T>(DependencyObject element) where T : DependencyObject
{
T retValue = null;
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
var type = child as T;
if (type != null)
{
retValue = type;
break;
}
retValue = FindDescendant<T>(child);
if (retValue != null)
{
break;
}
}
return retValue;
}
}
我的问题是事件的时间安排。单击按钮时,会立即加载新闻项目集,并在快速暂停后启动动画。是否有任何其他事件或我可以更改的内容,以便在动画开始之前项目不可见??
这里是示例的源代码link。
看起来列表视图试图在播放羽化动画之前播放 EntranceThemeTransition。如果您正在构建自己的动画,您可以尝试删除现有的 ListView.ItemContainerTransitions 集合。
感谢@user10930282,他是对的。解决方法是删除 ListView 的默认 ItemContainerTransitions:
<ListView x:Name="MyList">
.
.
.
<ListView.ItemContainerTransitions>
<TransitionCollection>
<!-- Empty collection to not have any transitions interrupt the composition Item animations -->
</TransitionCollection>
</ListView.ItemContainerTransitions>
.
.
.
</ListView>
我正在创建一个基于合成的动画,我想在加载每个 ListViewItem 时对其进行缩放。我有以下示例代码:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
MyList.ContainerContentChanging += (sender, args) =>
{
if (!args.InRecycleQueue)
{
args.ItemContainer.Loaded += (item, e) =>
{
var lvi = item as ListViewItem;
var panel = FindDescendant<ItemsStackPanel>(MyList);
var visual = ElementCompositionPreview.GetElementVisual(lvi);
var index = MyList.IndexFromContainer(lvi);
if (index >= panel.FirstVisibleIndex && index <= panel.LastVisibleIndex)
{
var width = (float)lvi.RenderSize.Width;
var height = (float)lvi.RenderSize.Height;
visual.CenterPoint = new Vector3(width / 2, height / 2, 0f);
var zoom = visual.Compositor.CreateVector3KeyFrameAnimation();
zoom.Duration = TimeSpan.FromSeconds(2);
zoom.DelayTime = TimeSpan.FromMilliseconds(index * 100);
zoom.InsertKeyFrame(0.0f, new Vector3(0.75f, 0.75f, 0f));
zoom.InsertKeyFrame(1.0f, new Vector3(1.0f, 1.0f, 0f));
visual.StartAnimation("Scale", zoom);
}
};
}
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var col = new List<int>();
for (var x = 0; x < 200; x++)
{
var z = new Random();
col.Add(z.Next(0, 1000));
}
MyList.ItemsSource = null;
MyList.ItemsSource = col;
}
private T FindDescendant<T>(DependencyObject element) where T : DependencyObject
{
T retValue = null;
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
var type = child as T;
if (type != null)
{
retValue = type;
break;
}
retValue = FindDescendant<T>(child);
if (retValue != null)
{
break;
}
}
return retValue;
}
}
我的问题是事件的时间安排。单击按钮时,会立即加载新闻项目集,并在快速暂停后启动动画。是否有任何其他事件或我可以更改的内容,以便在动画开始之前项目不可见??
这里是示例的源代码link。
看起来列表视图试图在播放羽化动画之前播放 EntranceThemeTransition。如果您正在构建自己的动画,您可以尝试删除现有的 ListView.ItemContainerTransitions 集合。
感谢@user10930282,他是对的。解决方法是删除 ListView 的默认 ItemContainerTransitions:
<ListView x:Name="MyList">
.
.
.
<ListView.ItemContainerTransitions>
<TransitionCollection>
<!-- Empty collection to not have any transitions interrupt the composition Item animations -->
</TransitionCollection>
</ListView.ItemContainerTransitions>
.
.
.
</ListView>