欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Windows Phone 实现类似“微博”下拉刷新效果

程序员文章站 2022-03-23 11:52:43
在我的O7上跑了下张善友写的博客园阅读APP,有很多体验上的想法,一时技痒想实现下拉刷新的效果。 如果要实现下拉的效果就需要三个状态,见下图: 第一种状态(提示下拉可以更新博客...

在我的O7上跑了下张善友写的博客园阅读APP,有很多体验上的想法,一时技痒想实现下拉刷新的效果。

如果要实现下拉的效果就需要三个状态,见下图:

第一种状态(提示下拉可以更新博客园新闻):

Windows Phone 实现类似“微博”下拉刷新效果

 

第二种状态(提示下拉的幅度已够可以释放进入更新操作)

Windows Phone 实现类似“微博”下拉刷新效果

 

第三种状态(提示正在更新,更新完毕回到第一个状态)

Windows Phone 实现类似“微博”下拉刷新效果

 

上面这个效果为了方便独立到一个UserControl中,代码如下:
XAML:
<UserControl x:Class="sdkRSSReaderCS.LoadingBox"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480">

    <Grid x:Name="LayoutRoot">
        <StackPanel Orientation="Horizontal">
            <Grid Margin="8,0,0,0" Width="50" Height="50">
                <Image x:Name="PulldownArrow" Width="50" Height="50" Source="/sdkRSSReaderCS;component/images/pulldown_arrow.png">
                    <Image.RenderTransform>
                        <RotateTransform x:Name="FlipTransform" CenterX="25" CenterY="25" Angle="180"/>
                    </Image.RenderTransform>
                    <Image.Resources>
                        <Storyboard x:Name="FlipDown">
                            <DoubleAnimation Storyboard.TargetName="FlipTransform"
                               Storyboard.TargetProperty="Angle"
                               From="0" To="180" Duration="0:0:0.2"/>
                        </Storyboard>
                        <Storyboard x:Name="FlipUp">
                            <DoubleAnimation Storyboard.TargetName="FlipTransform"
                               Storyboard.TargetProperty="Angle"
                               From="180" To="0" Duration="0:0:0.2"/>
                        </Storyboard>
                    </Image.Resources>
                </Image>
                <Image x:Name="SpinningBall" Source="/sdkRSSReaderCS;component/images/spinning_ball.png" Width="36" Height="36">
                    <Image.RenderTransform>
                        <RotateTransform x:Name="SpinTransform" CenterX="18" CenterY="18"/>
                    </Image.RenderTransform>
                    <Image.Resources>
                        <Storyboard x:Name="Spin">
                            <DoubleAnimation Storyboard.TargetName="SpinTransform"
                               Storyboard.TargetProperty="Angle"
                               From="0" To="360" Duration="0:0:1"
                               RepeatBehavior="Forever"/>
                        </Storyboard>
                    </Image.Resources>
                </Image>
            </Grid>
            <TextBlock x:Name="TextBlock" Margin="10,0,0,0"
                 VerticalAlignment="Center" FontSize="26"
                 Style="{StaticResource PhoneTextExtraLargeStyle}"
                 Foreground="{StaticResource PhoneAccentBrush}" />
        </StackPanel>
    </Grid>
</UserControl>

Cs代码:
    public partial class LoadingBox : UserControl
    {
        private string arrow;
        public static readonly DependencyProperty BusyProperty = DependencyProperty.Register("Busy", typeof(bool), typeof(LoadingBox), new PropertyMetadata(false));

        public LoadingBox()
        {
            InitializeComponent();
        }
        // Properties
        public string Arrow
        {
            get
            {
                return this.arrow;
            }
            set
            {
                if (this.arrow == null)
                {
                    if (value == "Invisible")
                        this.PulldownArrow.Visibility = Visibility.Collapsed;
                    else if (value == "Up")
                    {
                        this.FlipTransform.Angle = 0.0;
                        this.PulldownArrow.Visibility = Visibility.Visible;
                    }
                    else if (value == "Down")
                    {
                        this.FlipTransform.Angle = 180.0;
                        this.PulldownArrow.Visibility = Visibility.Visible;
                    }
                }
                else if (value == "Invisible")
                    this.PulldownArrow.Visibility = Visibility.Collapsed;
                else if (value == "Up")
                {
                    if (this.arrow == "Invisible")
                    {
                        this.FlipTransform.Angle = 0.0;
                        this.PulldownArrow.Visibility = Visibility.Visible;
                    }
                    else if (this.arrow == "Down") this.FlipUp.Begin();
                }
                else if (value == "Down")
                {
                    if (this.arrow == "Invisible")
                    {
                        this.FlipTransform.Angle = 180.0;
                        this.PulldownArrow.Visibility = Visibility.Visible;
                    }
                    else if (this.arrow == "Up") this.FlipDown.Begin();
                }
                this.arrow = value;
            }
        }

        public bool Busy
        {
            get
            {
                return (bool)base.GetValue(BusyProperty);
            }
            set
            {
                base.SetValue(BusyProperty, value);
                if (value)
                {
                    this.Arrow = "Invisible";
                    this.SpinningBall.Visibility = Visibility.Visible;
                    this.Spin.Begin();
                }
                else
                {
                    this.SpinningBall.Visibility = Visibility.Collapsed;
                    this.Spin.Stop();
                }
            }
        }

        public string Text
        {
            get
            {
                return this.TextBlock.Text;
            }
            set
            {
                this.TextBlock.Text = value;
            }
        }

    }

 下面是在引用的页面中的计算代码(里面的偏移量需要再具体引用的地方修改来适应相应的窗体和动作幅度):
#region ScrollView

        private void NewsScrollViewer_Loaded(object sender, RoutedEventArgs e)
        {
            this.newsScrollViewer = sender as ScrollViewer;
        }

        private void ScrollViewer_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            this.actualOffset = this.startOffset + this.startPoint - e.ManipulationOrigin.Y;
            if (this.actualOffset < -100 && !headLoadingBox.Busy)
            {
                Update();
            }
            if (this.actualOffset + 250 > this.newsScrollViewer.ScrollableHeight && !tailLoadingBox.Busy)
            {
                NextPage();
            }

        }

        private void ScrollViewer_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            this.startOffset = this.newsScrollViewer.VerticalOffset;
            this.startPoint = e.ManipulationOrigin.Y;
        }

        private void ScrollViewer_MouseEnter(object sender, MouseEventArgs e)
        {
            //this.startRelativePoint = e.GetPosition(this.TopPlaceholder).Y;
        }

        private void ScrollViewer_MouseMove(object sender, MouseEventArgs e)
        {
            this.actualOffset = this.startOffset + this.startRelativePoint - e.GetPosition(this.TopPlaceholder).Y;
            if (actualOffset < -100)
            {
                this.headLoadingBox.Arrow = "Up";
                this.headLoadingBox.Text = "松开就可以更新!";
            }
            if (this.actualOffset + 250 > this.newsScrollViewer.ScrollableHeight && !tailLoadingBox.Busy)
            {
                this.tailLoadingBox.Arrow = "Down";
                this.tailLoadingBox.Text = "松开就可以更新!";
            }
        }

作者:KKcat