UWP开发

FlipView实现天气AQI 效果

2017-09-09  本文已影响26人  Yanzipe

新建一个User Control文件依次在XAML,xaml.cs中加入如下代码

<!-- UserControl.xaml -->
<Grid Background = "White"
          Height="210" 
          Width="360"  
          CornerRadius="6" 
          BorderThickness="1" 
          BorderBrush="White">
        <Grid.RowDefinitions>
            <RowDefinition Height = "*" />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width = "*" />
                <ColumnDefinition Width= "*" />
            </Grid.ColumnDefinitions >
            <Grid Grid.Column= "0" >
                <StackPanel Orientation= "Vertical" >
                    <TextBlock x:Name= "WeatherQualityTextBlock"
                               Grid.Row= "0"
                               Margin= "20 10 0 0"
                               Text= "{x:Bind WeatherQuality,Mode=OneWay}"
                               Foreground= "#9B9B9B"
                               FontSize= "18"
                               FontStyle= "Normal" />
                    <StackPanel Orientation= "Horizontal"
                                VerticalAlignment= "Bottom" >
                        <FlipView x:Name="AQINumberFlipView" 
                                  HorizontalAlignment="Center"  
                                  VerticalAlignment="Center" 
                                  Height="60" 
                                  Width="60" 
                                  IsTapEnabled="False" 
                                  IsDoubleTapEnabled="False" 
                                  IsHoldingEnabled="False" 
                                  IsRightTapEnabled="False" 
                                  Loaded="AQINumberFlipView_Loaded" 
                                  Foreground="#9B9B9B" 
                                  Background="White"
                                  Margin="15 25 0 0">
                            <FlipView.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel Orientation="Vertical"/>
                                </ItemsPanelTemplate>
                            </FlipView.ItemsPanel>
                            <FlipView.ItemTemplate >
                                <DataTemplate >
                                    <TextBlock FontSize="50" Text="{Binding AQINumber}" ></TextBlock>
                                </DataTemplate>
                            </FlipView.ItemTemplate>
                        </FlipView>
                        <TextBlock Text= "AQI"
                                   Foreground= "#9B9B9B"
                                   FontSize= "20"
                                   VerticalAlignment= "Bottom" />
                    </StackPanel >
                </StackPanel >
            </Grid >
            <Grid x:Name="FloatingCircleIconGrid" 
                      Grid.Column= "1" >
            </Grid>
        </Grid >
        <StackPanel Orientation= "Horizontal"
                    Grid.Row= "1" 
                    Height="30">
            <Rectangle x:Name="AQIRectangle_1" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#CCCCCC" 
                       VerticalAlignment="Bottom"/>
            <Rectangle x:Name="AQIRectangle_2" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#B3B3B3" 
                       VerticalAlignment="Bottom"/>
            <Rectangle x:Name="AQIRectangle_3" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#999999" 
                       VerticalAlignment="Bottom"/>
            <Rectangle x:Name="AQIRectangle_4" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#808080" 
                       VerticalAlignment="Bottom"/>
            <Rectangle x:Name="AQIRectangle_5" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#666666" 
                       VerticalAlignment="Bottom"/>
            <Rectangle x:Name="AQIRectangle_6" 
                       Height= "10" 
                       Width= "60" 
                       Fill= "#4D4D4D" 
                       VerticalAlignment="Bottom"/>

        </StackPanel>
    </Grid >
//UserControl.xaml.cs
public class AQINumberClass
    {
        public int AQINumber { get; set; }
    }
    
    public sealed partial class AQIDetail : UserControl
    {
        DispatcherTimer AQINumberFlipViewTimerAnimation;
        List<AQINumberClass> AQINumList = new List<AQINumberClass>();
        List<Ellipse> FloatingCircleList = new List<Ellipse>();
        int TickTime = 0;
        int aqi = 0;
        Random random = new Random();

        public AQIDetail()
        {
            this.InitializeComponent();
            
            // AQI Number FlipView Animation
            AQINumberFlipViewTimerAnimation = new DispatcherTimer();
            AQINumberFlipViewTimerAnimation.Interval = new TimeSpan(10);//10ms
            AQINumberFlipViewTimerAnimation.Tick += AQINumberFlipViewTimer_Tick;//Refresh
            AQINumberFlipViewTimerAnimation.Start();
            
        }

        public static readonly DependencyProperty WeatherQualityProperty =
            DependencyProperty.Register("WeatherQuality", typeof(string), typeof(AQIDetail), new PropertyMetadata("--"));

        public string WeatherQuality
        {
            get => (string)GetValue(WeatherQualityProperty);
            set => SetValue(WeatherQualityProperty, value);
        }

        public static readonly DependencyProperty AQINumberProperty =
            DependencyProperty.Register("AQINumber", typeof(string), typeof(AQIDetail), new PropertyMetadata("0",OnAQINumberChanged));

        private static void OnAQINumberChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            AQIDetail _AQIDetail = d as AQIDetail;
            _AQIDetail.aqi = Convert.ToInt32(_AQIDetail.AQINumber);
            //AQI Rectangle Animation
            _AQIDetail.AQIRectangleAnimation();
            //AQI List Add
            for (int i = 0; i <= _AQIDetail.aqi; i++)
            {
                _AQIDetail.AQINumList.Add(new AQINumberClass { AQINumber = i });
            }
            //AQINumberFlipView Binding
            _AQIDetail.AQINumberFlipView.ItemsSource = _AQIDetail.AQINumList;
            //AQI Floationg Circle Add
            int AQILevel = _AQIDetail.GetAQILevel(_AQIDetail.aqi);
            int rgb = 0;
            for (int i = 0; i <= AQILevel; i++)
            {
                Ellipse ellipse = new Ellipse();
                ellipse.Height = _AQIDetail.random.Next(1, 20);
                ellipse.Width = ellipse.Height;
                rgb = _AQIDetail.random.Next(100, 255);
                ellipse.Fill = new SolidColorBrush(Color.FromArgb(255, (byte)rgb, (byte)rgb, (byte)rgb));
                ellipse.Margin = new Thickness(_AQIDetail.random.Next(-60, 60), _AQIDetail.random.Next(-60, 60), _AQIDetail.random.Next(-60, 60), _AQIDetail.random.Next(-60, 60));
                _AQIDetail.FloatingCircleIconGrid.Children.Add(ellipse);
                _AQIDetail.FloatingCircleList.Add(ellipse);
            }
            //AQI Floating Circle Animation
            _AQIDetail.AQIFloatingCircleAnimation();
        }

        public string AQINumber
        {
            get => (string)GetValue(AQINumberProperty);
            set => SetValue(AQINumberProperty, value);
        }


        private void AQIRectangleAnimation()
        {
            int aqi = Convert.ToInt32(AQINumber);
            var targetRectangle = new Rectangle();
            if (aqi <= 50)
                targetRectangle = AQIRectangle_1;
            else if (aqi > 50 && aqi <= 100)
                targetRectangle = AQIRectangle_2;
            else if (aqi > 100 && aqi <= 150)
                targetRectangle = AQIRectangle_3;
            else if (aqi > 150 && aqi <= 200)
                targetRectangle = AQIRectangle_4;
            else if (aqi > 200 && aqi <= 300)
                targetRectangle = AQIRectangle_5;
            else if (aqi > 300)
                targetRectangle = AQIRectangle_6;

            var storyBoard = new Storyboard();
            var extendAnimation1 = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)), From = 0, To = targetRectangle.Height * 2, EnableDependentAnimation = true };


            Storyboard.SetTarget(extendAnimation1, targetRectangle);
            Storyboard.SetTargetProperty(extendAnimation1, "Height");


            storyBoard.Children.Add(extendAnimation1);

            storyBoard.AutoReverse = false;
            storyBoard.Begin();
        }

        private void AQIFloatingCircleAnimation()
        {
            TranslateTransform translateTransform = new TranslateTransform();
            foreach (var circle in FloatingCircleList)
            {

                translateTransform.X = random.Next(-2, 2);
                translateTransform.Y = random.Next(-2, 2);
                circle.RenderTransform = translateTransform;

                var storyboard = new Storyboard();
                var XAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)) };
                var YAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)) };
                storyboard.Children.Add(XAnimation);
                storyboard.Children.Add(YAnimation);
                Storyboard.SetTarget(XAnimation, translateTransform);
                Storyboard.SetTarget(YAnimation, translateTransform);

                Storyboard.SetTargetProperty(XAnimation, "X");
                Storyboard.SetTargetProperty(YAnimation, "Y");

                XAnimation.From = translateTransform.X;
                YAnimation.From = translateTransform.Y;
                XAnimation.To = translateTransform.X + 2;
                YAnimation.To = translateTransform.Y + 2;
                //Repeat
                storyboard.RepeatBehavior = RepeatBehavior.Forever;
                storyboard.Begin();
                storyboard.AutoReverse = true;
            }
        }

        private int GetAQILevel(int _aqi)
        {
            int _level = 0;
            if (_aqi <= 50)
                _level = 1;
            else if (_aqi > 50 && _aqi <= 100)
                _level = 2;
            else if (_aqi > 100 && _aqi <= 150)
                _level = 3;
            else if (_aqi > 150 && _aqi <= 200)
                _level = 4;
            else if (_aqi > 200 && _aqi <= 300)
                _level = 5;
            else if (_aqi > 300)
                _level = 6;
            return _level;
        }



        private void AQINumberFlipViewTimer_Tick(object sender, object e)
        {
            if (AQINumberFlipView.SelectedIndex < AQINumList.Count - 1)
            {
                AQINumberFlipView.SelectedIndex++;
                TickTime++;
            }
            if (TickTime == AQINumList.Count - 1)
                AQINumberFlipViewTimerAnimation.Stop();
        }



        /// <summary>
        /// Narrow the button in the FlipView
        /// </summary>
        private void AQINumberFlipView_Loaded(object sender, RoutedEventArgs e)
        {
            Grid grid = (Grid)VisualTreeHelper.GetChild(AQINumberFlipView, 0);
            for (int i = grid.Children.Count - 1; i >= 0; i--)
                if (grid.Children[i] is Button)
                    grid.Children.RemoveAt(i);
        }
    }

//MainPage.xaml
<control:AQIDetail x:Name="AQIDetailControl"  AQINumber="50" WeatherQuality="优质"/>

效果如图:

AQIFlipView.gif
GitHub:https://github.com/Yanzipe/SimpleWeather/tree/master/SimpleWeather/Control
上一篇 下一篇

猜你喜欢

热点阅读