FlipView实现天气AQI 效果

新建一个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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容