C# WPF 低仿网易云音乐(PC)Banner动画控件

由于技术有限没能做到一模一样的动画,只是粗略地做了一下。动画有点生硬,还有就是没做出网易云音乐的立体感。代码非常简单粗暴而且我也写有注释,这里就不多啰嗦了,直接贴代码。

算了,啰嗦几句。原理是这样的,建立一个用户控件,在控件内添加3个border,对border进行缩放和移动动画。

低仿效果

网易云音乐原版

代码

后台

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace 网易云音乐Banner动画.Controls
{
    /// <summary>
    /// CloudMusicBanner.xaml 的交互逻辑
    /// </summary>
    public partial class CloudMusicBanner : UserControl
    {

        //代码所用涉及时间单位均是:秒
        #region 一些变量
        //左、中、右三张banner的位置
        double leftlocation = 0, centerlocation = 0, rightlocation = 0;
        //每张banner的动画执行时间
        double AnimationTime = 0.4;
        //非中间banner的遮盖层透明度
        double bopacity = 0.65;
        //没有交互时动画自动执行间隔时间
        double timeranimation_time = 4;
        //动画播放状态(当前动画是否在执行)
        bool isplay = false;
        //三个banner border变量,用于暂时保存
        Border b_left, b_center, b_right;
        //通用缓动函数,提升动画流畅感
        EasingFunctionBase easeFunction;
        //banner集合,用于定位和记录border的位置(左,中,右)
        Dictionary<Location, Border> Banners = new Dictionary<Location, Border>();
        DispatcherTimer timeranimation;
        #endregion

        public CloudMusicBanner()
        {
            InitializeComponent();

            //将三张banner(border)添加到banner集合
            Banners.Add(Location.Left, left);
            Banners.Add(Location.Center, center);
            Banners.Add(Location.Right, right);

            //控件加载完成后
            Loaded += (e, c) =>
            {
                //首次启动设置三张banner的位置、大小信息
                SetLocation(Location.Left, left);
                SetLocation(Location.Center, center);
                SetLocation(Location.Right, right);

                //启动定时器,用于自动播放滚动动画
                TimerAnimationStart();
            };

            //初始化缓动函数
            //quadraticease的easeout mode是从快到慢
            //参考了博客:http://www.cnblogs.com/xwlyun/archive/2012/09/11/2680579.html
            easeFunction = new QuadraticEase()
            {
                EasingMode = EasingMode.EaseOut
            };

            //初始化定时器
            timeranimation = new DispatcherTimer();
            //设置定时器的间隔时间
            timeranimation.Interval = TimeSpan.FromSeconds(timeranimation_time);

        }

        #region 交互事件

        private void UserControl_MouseEnter(object sender, MouseEventArgs e)
        {
            //鼠标移入控件时显示两个“左/右”图标按钮
            toleftbtn.Opacity = 1;
        }

        private void UserControl_MouseLeave(object sender, MouseEventArgs e)
        {
            //鼠标移出控件时隐藏两个“左/右”图标按钮

            toleftbtn.Opacity = 0;
        }

        private void toleftbtn_Click(object sender, RoutedEventArgs e)
        {
            //向左图标按钮点击
            LeftAnimation();
        }

        private void torightbtn_Click(object sender, RoutedEventArgs e)
        {
            RightAnimation();
        }
        #endregion

        //左切换动画时三张banner向右滚动
        /*
         * 即中间的border移动至:右
         * 右边的border移动至:左
         * 左边的border移动至:中
         */
        #region 左切换动画
        public void LeftAnimation()
        {
            //启动动画时停止定时器
            timeranimation.Stop();
            //设置动画播放状态为真
            isplay = true;

            //启动相应的动画
            LefttoCenterAnimation();

            CentertoRightAnimation();

            RighttoLeftAnimation();

        }
        //【仅注释此方法,以下代码均大多重复故不再注释】
        #region 左切换动画-中向右动画
        public void CentertoRightAnimation()
        {
            //记录动画结束后的位置,即当动画结束后中间的BORDER移动到右变成了右,代码:Banners[Location.Right] = b_center;
            b_center = Banners[Location.Center];

            //设置一下border的显示层级
            Grid.SetZIndex(Banners[Location.Center], 2);

            //获取透明遮盖图层,设置透明度
            /*
             * <Grid Background="Black" Panel.ZIndex="2"></Grid>
             * 透明遮盖图层在设计代码中的每个border内
             *
             */
            GetOpacityGrid(b_center).Opacity = bopacity;

            //定义一个缩放转换对象(用于banner从大到小的动画)
            ScaleTransform scale = new ScaleTransform();
            //需要设置中心点y坐标为控件的高度,不设置的话border是靠在顶部执行动画的。
            scale.CenterY = this.ActualHeight;

            //定义一个水平移动转换对象
            TranslateTransform ts = new TranslateTransform();

            //定义一个转换集合
            TransformGroup group = new TransformGroup();
            //将上面的缩放、平移转换对象添加到集合
            group.Children.Add(scale);
            group.Children.Add(ts);

            //将转换集合赋予给中心banner
            Banners[Location.Center].RenderTransform = group;

            //定义一个缩放动画
            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {
                //从1(100%即默认比例)
                From = 1,
                //到0.95(95%即从默认比例缩小到95%的比例大小)
                To = 0.95,
                //设置缓动函数
                EasingFunction = easeFunction,
                //动画执行所需时间
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            //定义一个移动动画(用于banner从左到右.....移动动画等)
            DoubleAnimation moveAnimation = new DoubleAnimation()
            {
                //从中心banner位置
                From = centerlocation,
                //移动到右banner位置
                To = rightlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };
            //启动缩放动画
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion
        #region 左切换动画-右向左动画
        public void RighttoLeftAnimation()
        {
            b_right = Banners[Location.Right];

            Grid.SetZIndex(Banners[Location.Right], 1);
            GetOpacityGrid(b_right).Opacity = bopacity;

            ScaleTransform scale = new ScaleTransform();   //缩放
            scale.CenterY = this.ActualHeight;
            TranslateTransform ts = new TranslateTransform();//平移

            TransformGroup group = new TransformGroup();
            group.Children.Add(scale);
            group.Children.Add(ts);

            Banners[Location.Right].RenderTransform = group;

            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {
                From = 0.85,
                To = 0.95,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            DoubleAnimation moveAnimation = new DoubleAnimation()
            {

                From = rightlocation,
                To = leftlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            //scaleAnimation.Completed += new EventHandler(scaleAnimation_Completed);
            //  AnimationClock clock = scaleAnimation.CreateClock();
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion
        #region 左切换动画-左向中动画
        public void LefttoCenterAnimation()
        {
            b_left = Banners[Location.Left];

            Grid.SetZIndex(Banners[Location.Left], 3);

            GetOpacityGrid(b_left).Opacity = 0;

            ScaleTransform scale = new ScaleTransform();   //缩放  

            //scale.CenterX = 0;
            scale.CenterY = this.ActualHeight;
            TranslateTransform ts = new TranslateTransform();//平移

            TransformGroup group = new TransformGroup();
            group.Children.Add(scale);
            group.Children.Add(ts);

            Banners[Location.Left].RenderTransform = group;

            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {

                From = 0.95,
                To = 1,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            DoubleAnimation moveAnimation = new DoubleAnimation()
            {

                From = leftlocation,
                To = centerlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            scaleAnimation.Completed += new EventHandler(LeftAnimation_Completed);
            //  AnimationClock clock = scaleAnimation.CreateClock();
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion

        #region 动画结束
        private void LeftAnimation_Completed(object sender, EventArgs e)
        {
            //动画结束后将banner集合的位置重新设置
            Banners[Location.Left] = b_right;
            Banners[Location.Center] = b_left;
            Banners[Location.Right] = b_center;
            //此时动画结束
            isplay = false;
            //启动定时器
            TimerAnimationStart();
        }
        #endregion
        #endregion

        #region 右切换动画
        public void RightAnimation()
        {
            timeranimation.Stop();

            isplay = true;

            LefttoRightAnimation();

            CentertoLeftAnimation();

            RighttoCenterAnimation();

        }

        #region 右切换动画-左向右动画
        public void LefttoRightAnimation()
        {
            b_left = Banners[Location.Left];
            Grid.SetZIndex(Banners[Location.Left], 1);
            GetOpacityGrid(b_left).Opacity = bopacity;
            ScaleTransform scale = new ScaleTransform();   //缩放
            scale.CenterY = this.ActualHeight;

            TranslateTransform ts = new TranslateTransform();//平移

            TransformGroup group = new TransformGroup();
            group.Children.Add(scale);

            group.Children.Add(ts);

            Banners[Location.Left].RenderTransform = group;

            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {
                From = 0.85,
                To = 0.95,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };
            DoubleAnimation moveAnimation = new DoubleAnimation()
            {

                From = leftlocation,
                To = rightlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion
        #region 右切换动画-中向左动画
        public void CentertoLeftAnimation()
        {
            b_center = Banners[Location.Center];

            Grid.SetZIndex(Banners[Location.Center], 2);
            GetOpacityGrid(b_center).Opacity = bopacity;

            ScaleTransform scale = new ScaleTransform();   //缩放
            scale.CenterY = this.ActualHeight;
            TranslateTransform ts = new TranslateTransform();//平移

            TransformGroup group = new TransformGroup();
            group.Children.Add(scale);
            group.Children.Add(ts);

            Banners[Location.Center].RenderTransform = group;

            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {
                From = 1,
                To = 0.95,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            DoubleAnimation moveAnimation = new DoubleAnimation()
            {

                From = centerlocation,
                To = leftlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            //scaleAnimation.Completed += new EventHandler(scaleAnimation_Completed);
            //  AnimationClock clock = scaleAnimation.CreateClock();
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion
        #region 右切换动画-右向中动画
        public void RighttoCenterAnimation()
        {
            b_right = Banners[Location.Right];
            //SetZindex(b_right);
            Grid.SetZIndex(Banners[Location.Right], 3);

            GetOpacityGrid(b_right).Opacity = 0;

            ScaleTransform scale = new ScaleTransform();   //缩放  

            //scale.CenterX = 0;
            scale.CenterY = this.ActualHeight;
            TranslateTransform ts = new TranslateTransform();//平移

            TransformGroup group = new TransformGroup();
            group.Children.Add(scale);
            group.Children.Add(ts);

            Banners[Location.Right].RenderTransform = group;

            DoubleAnimation scaleAnimation = new DoubleAnimation()
            {
                To = 1,
                From = 0.95,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            DoubleAnimation moveAnimation = new DoubleAnimation()
            {

                From = rightlocation,
                To = centerlocation,
                EasingFunction = easeFunction,
                Duration = TimeSpan.FromSeconds(AnimationTime)

            };

            scaleAnimation.Completed += new EventHandler(RightAnimation_Completed);
            //  AnimationClock clock = scaleAnimation.CreateClock();
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

            //启动平移动画
            ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation);

        }

        #endregion
        #region 动画结束
        private void RightAnimation_Completed(object sender, EventArgs e)
        {
            Banners[Location.Left] = b_center;
            Banners[Location.Center] = b_right;
            Banners[Location.Right] = b_left;
            isplay = false;
            TimerAnimationStart();
        }
        #endregion
        #endregion

        #region 初始化设置控件位置
        //定义一个枚举类用于标识左中右三个banner(border),方便操作时获取到。
        public enum Location
        {
            Left, Center, Right
        }
        //设置三个border的大小和位置
        public void SetLocation(Location l, Border g)
        {

            //banner的大小
            g.Width = 540;
            g.Height = 200;

            //给除中间banner外的border缩小一些
            ScaleTransform scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = 0.95;
            scaleTransform.ScaleY = 0.95;
            scaleTransform.CenterY = this.ActualHeight;
            //获取设置遮盖层的透明度
            Grid opacity_grid = GetOpacityGrid(g);
            opacity_grid.Opacity = bopacity;
            switch (l)
            {
                case Location.Left:

                    TranslateTransform tt_left = new TranslateTransform()
                    {
                        X = 0
                    };
                    TransformGroup group_left = new TransformGroup();
                    group_left.Children.Add(tt_left);
                    group_left.Children.Add(scaleTransform);
                    g.RenderTransform = group_left;

                    break;
                case Location.Center:
                    opacity_grid.Opacity = 0;

                    TransformGroup group_center = new TransformGroup();

                    //计算中心banner的x位置
                    centerlocation = (this.ActualWidth - g.ActualWidth) / 2;
                    TranslateTransform tt_center = new TranslateTransform()
                    {
                        X = centerlocation
                    };
                    group_center.Children.Add(tt_center);
                    g.RenderTransform = group_center;
                    Grid.SetZIndex(g, 3);
                    break;
                case Location.Right:
                    //Grid.SetZIndex(g, 3);

                    //计算右banner的X位置
                    rightlocation = (this.ActualWidth - Banners[Location.Left].ActualWidth * 0.95);

                    TranslateTransform tt_right = new TranslateTransform()
                    {
                        X = rightlocation
                    };
                    TransformGroup group_right = new TransformGroup();
                    //这里要注意先后顺序,否则位置会有偏差,必须先缩放再设置X坐标。
                    group_right.Children.Add(scaleTransform);
                    group_right.Children.Add(tt_right);
                    g.RenderTransform = group_right;

                    break;
            }

        }
        #endregion

        //获取透明覆盖层
        //代码来自:https://www.cnblogs.com/udoless/p/3381411.html
        #region 获取透明覆盖层
        public Grid GetOpacityGrid(DependencyObject g)
        {
            Grid opacity_grid = GetChild<Grid>(g, typeof(Grid));
            opacity_grid = GetChild<Grid>(opacity_grid, typeof(Grid));
            return opacity_grid;
        }
        public T GetChild<T>(DependencyObject obj, Type typename) where T : FrameworkElement
        {
            DependencyObject child = null;
            List<T> childList = new List<T>();

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).GetType() == typename))
                {
                    return ((T)child);
                }

            }
            return null;
        }
        #endregion

        #region 定时唤醒动画
        public void TimerAnimationStart()
        {
            if (timeranimation.IsEnabled == false)
            {

                timeranimation.Start();
            }
            timeranimation.Tick += (e, c) =>
            {

                timeranimation.Stop();
                if (isplay == false)
                {
                    RightAnimation();
                }
            };
        }
        #endregion
    }
}

前台

<UserControl x:Class="网易云音乐Banner动画.Controls.CloudMusicBanner"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 

             d:DesignHeight="200" d:DesignWidth="762" MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave"

             >
    <Grid>
        <!--两个图标按钮,鼠标进入时显示-->
        <Button Name="toleftbtn" Opacity="0" Click="toleftbtn_Click" BorderThickness="0" HorizontalAlignment="Left" Background="Transparent" Panel.ZIndex="99" Width="50" Height="50" Cursor="Hand">
            <Image Source="/网易云音乐Banner动画;component/Res/左.png" Width="16" Height="16"></Image>
        </Button>
        <Button Name="torightbtn" Opacity="{Binding ElementName=toleftbtn,Path=Opacity}" Click="torightbtn_Click" BorderThickness="0" HorizontalAlignment="Right" Background="Transparent" Panel.ZIndex="99" Width="50" Height="50" Cursor="Hand">
            <Image Source="/网易云音乐Banner动画;component/Res/右.png" Width="16" Height="16"></Image>
        </Button>

        <Grid  HorizontalAlignment="Left">

           <!--左边的banner-->
            <Border BorderBrush="#000000" BorderThickness="0" Width="540" Name="left" Background="Black">
                <Grid>
                    <!--透明遮盖层-->
                    <Grid Background="Black" Panel.ZIndex="2"></Grid>
                    <!--banner图片-->
                    <Image Source="/网易云音乐Banner动画;component/Res/banner1.jpg" Stretch="Fill"></Image>
                </Grid>
            </Border>

            <!--中间的banner-->
            <Border BorderBrush="#96b0b3" BorderThickness="0" Width="540" Name="center" Background="Yellow" >
                <Grid>
                    <Grid Background="Black" Panel.ZIndex="2"></Grid>
                    <Image Source="/网易云音乐Banner动画;component/Res/banner2.jpg" Stretch="Fill"></Image>
                </Grid>
            </Border>

            <!--右边的banner-->
            <Border BorderBrush="#ab1491" BorderThickness="1" Name="right" Background="Red">
                <Grid>
                    <Grid Background="Black" Panel.ZIndex="2"></Grid>
                    <Image Source="/网易云音乐Banner动画;component/Res/banner3.jpg" Stretch="Fill"></Image>
                </Grid>

            </Border>

        </Grid>
    </Grid>
</UserControl>

被你发现了

项目下载在这

点我下载项目源码

原文地址:https://www.cnblogs.com/berumotto/p/8259841.html

时间: 2024-08-19 03:24:13

C# WPF 低仿网易云音乐(PC)Banner动画控件的相关文章

C# WPF 低仿网易云音乐(PC)歌词控件

原文:C# WPF 低仿网易云音乐(PC)歌词控件 提醒:本篇博客记录了修改的过程,废话比较多,需要项目源码和看演示效果的直接拉到文章最底部~ 网易云音乐获取歌词的api地址 http://music.163.com/api/song/media?id=歌曲ID 填写歌曲的id即可获取到json格式的数据(歌曲ID获取的方法是:点击分享按钮>其他分享>复制链接,就可以在链接中看到了): {"songStatus":0,"lyricVersion":10,

WPF 仿网易云音乐PC端

简介 (1)左侧菜单采用 Expander+RadioButton: MVVM 绑定 后台的一个Menu 属性(使用转换器) (2)右侧采用Frame绑定Page的方式 ## [更新日志] ### 1.0.0.2 (2018-11-5)1. 本地音乐和云盘都可以使用.2. 云盘播放音乐下载逻辑等待优化.3. 本地搜索&缓存音乐等待优化.3. 音频解码器等待优化. ### 1.0.0.1 (2018-11-5)1. Frame导航完善.2. 本地音乐界面初步完善. ### 1.0.0.0 (201

《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目

CloudReader 一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目.项目采取的是Retrofit + RxJava + MVVM-DataBinding架构开发.开发中所遇到的各种问题已归纳在这里. github地址:CloudReader What can be learned about this project 那么,从本项目中你能学到哪些知识呢? 1.干货集中营内容与豆瓣电影书籍内容. 2.高仿网易云音乐歌单

Android实战之酷云--&gt;仿网易云音乐开发

我的个人网站 Xuejianxin's Blog Google Blog Xuejianxin's Blog Android自定义View学习 Android自定义View之常用工具源码分析 Android自定义View之onMeasure()源码分析 Android自定义View之onLayout()源码分析 Android自定义View之对TouchEvent的处理 Android自定义View之draw原理分析 如果觉得我的文章还行的话,也可以关注我的公众号,里面也会第一时间更新,并且会有

仿网易云音乐 专辑图片折叠轮播

仿网易云音乐 专辑图片折叠轮播 先不多说现上一张效果图 首先简述一下实现原理 1.首先让我们的imageview**动起来** 其实是不断的.invalidate();函数 让他不断的调用ondarw函数 (显然我们不必要不断的调用ondarw函数 只有在我们让他动的时候调用即可 所以我们要声明一个变量记录change记录是否产生动画) 2.实现我们的可折叠效果 Matrix的setPolyToPoly方法的使用 可参考(http://blog.csdn.net/lmj623565791/art

仿网易云音乐的播放进度条

仿网易云音乐的播放进度条,有三种状态:播放.暂停和拖动,只是实现了动画和主要的交互逻辑,其他细节(如暂停音乐的播放等)还需要自己完善: DKPlayerBar 是继承于UIControl的,如果想获取播放\暂停的事件建议用标准的addTarget方法: [playerBar addTarget:self action:@selector(playOrPause) forControlEvents:UIControlEventValueChanged]; 然后在DKPlayerBar里监听DKPl

高仿网易云音乐客户端的Home页面切换Tabhost-IT蓝豹

1.高仿网易云音乐客户端的Home页面切换Tabhost 高仿网易云音乐客户端的Home页面切换Tabhost,并且三角形是透明的,实现方式,自定义AnimTabsView继承 RelativeLayout 里面对当前选中的item 处理 三角形变成透明效果,即在onDraw 里面对三角形图片经行透明度处理,AnimTabsView提供 setOnAnimTabsItemViewChangeListener方法的onChange()用来监听点击切换tabhost. 下面主要是AnimTabsVi

仿网易云音乐部分UI实现

引言 有一段时间闲着没事做,突发奇想,于是就去防了部分网易云UI的界面,最开始是想仿成这个样子: 于是反编译了网易云的源文件,果不其然混淆的很彻底,表示并不能看懂,诺: 里面的代码大部分都是smali语法,也就是这样的: .class public La/auu/a; .super Ljava/lang/Object; .source "a.java" # static fields .field public static final CRLF:I = 0x4 .field priv

Python脚本用于定时关闭网易云音乐PC客户端

本文主要讲述如何使用Python在指定的秒数后关闭Windows上运行的程序(此程序以网易云音乐为例).本文的背景是昨晚发现网易云音乐的PC客户端没有定时关闭的功能,可以使用Python编写一个简单的脚本,用于定时关闭这样的计划任务.经过改良后,可以对此做一些有用的扩展,用于日常运维中. 为什么使用Python来做这件事? 用cmd.计划任务或者批处理做这件事不可以吗?如果说忽略过程,只看结果的话,这些方式确实可能更简单也能达到目的,但是通过Python来做可以从过程和结果两个方面获得很多好处: