首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有类似Groove的快速返回标头的ListView

具有类似Groove的快速返回标头的ListView
EN

Stack Overflow用户
提问于 2016-08-17 06:16:07
回答 2查看 203关注 0票数 3

当向下滚动时,Groove将标题向上移动到可见区域之外,就像常规的ListView标题一样。当向上滚动时,它会立即将标题向下移动到可见区域,而不管当前的垂直滚动偏移量。标题似乎是ListView内容的一部分,因为滚动条包含标题。

如何在Windows 10 UWP应用程序中实现这一点?

EN

回答 2

Stack Overflow用户

发布于 2016-08-18 21:34:52

您可以通过利用ListView's内部的ScrollViewer's ViewChanged事件来完成此操作。

首先,您需要获取内部ScrollViewer。这是最简单的版本,但您可能希望使用众多VisualTreeHelper扩展中的一个来实现更安全、更容易的操作:

代码语言:javascript
复制
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var border = VisualTreeHelper.GetChild(MyListView, 0);
    var scrollviewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;

    scrollviewer.ViewChanged += Scrollviewer_ViewChanged;
}

在EventHandler中,您可以根据滚动方向更改标题的可见性。

代码语言:javascript
复制
private void Scrollviewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
    var sv = sender as ScrollViewer;

    if (sv.VerticalOffset > _lastVerticalOffset)
    {
        MyHeader.Visibility = Visibility.Collapsed;
    }
    else
    {
        MyHeader.Visibility = Visibility.Visible;
    }
}

这是基本的想法。你可能不想添加一些平滑的动画,而不仅仅是改变可见性。

票数 1
EN

Stack Overflow用户

发布于 2016-08-23 19:24:36

在环顾四周并进行了一些实验之后,我现在可以回答我自己的问题了。

可以使用基于表达式的composition animation来调整标题相对于滚动的Y偏移量。这个想法是基于这个answer的。我在GitHub上准备了一个完整的工作示例。

动画是在ListView的SizeChanged事件中准备的:

代码语言:javascript
复制
ScrollViewer scrollViewer = null;
private double previousVerticalScrollOffset = 0.0;
private CompositionPropertySet scrollProperties;
private CompositionPropertySet animationProperties;

SizeChanged += (sender, args) =>
{
    if (scrollProperties == null)
        scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);

    var compositor = scrollProperties.Compositor;

    if (animationProperties == null)
    {
        animationProperties = compositor.CreatePropertySet();
        animationProperties.InsertScalar("OffsetY", 0.0f);
    }

    var expressionAnimation = compositor.CreateExpressionAnimation("animationProperties.OffsetY - ScrollingProperties.Translation.Y");

    expressionAnimation.SetReferenceParameter("ScrollingProperties", scrollProperties);
    expressionAnimation.SetReferenceParameter("animationProperties", animationProperties);

    var headerVisual = ElementCompositionPreview.GetElementVisual((UIElement)Header);
    headerVisual.StartAnimation("Offset.Y", expressionAnimation);
};

animationProperties中的OffsetY变量将驱动标头的OffsetY属性的动画。在ScrollViewer的ViewChanged事件中更新OffsetY变量:

代码语言:javascript
复制
scrollViewer.ViewChanged += (sender, args) =>
{
    float oldOffsetY = 0.0f;
    animationProperties.TryGetScalar("OffsetY", out oldOffsetY);

    var delta = scrollViewer.VerticalOffset - previousVerticalScrollOffset;
    previousVerticalScrollOffset = scrollViewer.VerticalOffset;

    var newOffsetY = oldOffsetY - (float)delta;

    // Keep values within negativ header size and 0
    FrameworkElement header = (FrameworkElement)Header;
    newOffsetY = Math.Max((float)-header.ActualHeight, newOffsetY);
    newOffsetY = Math.Min(0, newOffsetY);

    if (oldOffsetY != newOffsetY)
        animationProperties.InsertScalar("OffsetY", newOffsetY);
};

虽然这样可以正确地设置动画,但标题不会堆叠在ListView项的顶部。因此,最后一块拼图是降低ListView的ItemsPanelTemplate的ZIndex:

代码语言:javascript
复制
<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <ItemsStackPanel Canvas.ZIndex="-1" />
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

这就是结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38985339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档