[UWP] from scratch to create and publish a Pomodoro

Original: [UWP] from scratch to create and publish a Pomodoro

1. themselves with their own Pomodoro #

On the PC I have been using the "small tomato" as my Pomodoro software, after I put it on display on the sub-maximizing, so not only can it do to the part, but also tell my colleagues, "I'm concentrate jobs". But I always dislike it enough to feel pleasure, always wanted to write a Pomodoro software, just recently applied for a long time did not write UWP very itchy, so he's taking the time to write a personal use Pomodoro and posted to the Microsoft application store.

The results also do not feel joy.

In addition, I also had originally intended to achieve animation with Storyboard, but fire fire always advised me not to do Storyboard, use the Composition API to do animation. Storyboard ability there is a limit, I learned from a brief career which UWP one thing, the more people playing the animation, the animation, the more likely because the situation did not expect to fail ...... unless beyond the Storyboard. So I do not do Sotryboard friends.

Microsoft's application store is a good platform, WPF programmers can easily create a UWP based on existing knowledge and applications published to an app store. Especially now that Microsoft's audit more relaxed, as long as the application is worthy of their own conscience usually be approved. Although because of my own shop ventilation is very difficult to download it to your application . This article will explain the project to create the UWP publish the entire process to the store.

2. Requirements #

I just want to be a countdown Timer, the way to play the new API UWP, so in principle the simpler the better, then think of what to do.

Many Pomodoro software will provide a list of tasks function, can also chart showing the number of tomato, quantity to complete the task of statistics. But I have To-Do and Azure Devops, will usually work recorded on OneNote, I have more confidence I put the data into Microsoft Pomodoro there and not there, and I think Pomodoro measure of whether to perform well standard is my job, not the chart is not too interested in showing me the number of tomatoes, so I charts, statistics, task lists these functions.

Having said that fact, or because I am lazy, usually go to work so much data has been processed, the chart I have tired of their own do not want to play these things work, and storing data to be held responsible, I do not want negative responsibility.

3. Create a project #

First, install Windows Template Studio , it can help developers easily create UWP project.

Create a new project in the interface options after installation Windows Template Studio(Universal Windows), and then create UWP application already contains a basic function of the control window to open the wizard step by step.

Project name OnePomodoro, project type selection Blank, Design pattern selected Prism, as used in WPF accustomed Prsim. But I do not know how to use UWP in Prism, so I did not intend to immediately use, only a small project breezed CodeBehind a shuttle.

Select the Settings page Item page. Added features items like a very interesting Toast Notifications, Live Tile and a series of notifications.

Wait a few minutes, one containing the basic functions of the UWP project has been created, the project also close to a lot of tips Todo items need to be addressed, operating results are as follows:

然后添加Microsoft.Toolkit.Uwp.UIMicrosoft.Toolkit.Uwp.UI.Animations引用,这两个包是Windows Community Toolkit的一部分,提供了很多有用的Converter和动画。

第一次运行应用时会弹出一些示例通知,现在还不需要做到这么全面,找到App.xaml.cs里的LaunchApplicationAsync把里面一些通知相关的代码注释掉,然后就可以开始实现我们的功能了。

 
 
Copy
protected override async Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args) { await LaunchApplicationAsync(PageTokens.MainPage, null); } private async Task LaunchApplicationAsync(string page, object launchParam) { await ThemeSelectorService.SetRequestedThemeAsync(); NavigationService.Navigate(page, launchParam); SetupTitlebar(); Window.Current.Activate(); //await Container.Resolve<IWhatsNewDisplayService>().ShowIfAppropriateAsync(); //await Container.Resolve<IFirstRunDisplayService>().ShowIfAppropriateAsync(); //Container.Resolve<ILiveTileService>().SampleUpdate(); //Container.Resolve<IToastNotificationsService>().ShowToastNotificationSample(); }

4. 具体实现#

最终效果就是这样,一个单页面的应用,点击开始启动工作的计时器,点击停止(或者倒计时结束)转到休息的计时器,如此往返几次,一天的工资就到手了。

很多计时器是个由分针和秒针组成的表盘,但我已经玩腻了这种做法,简单些反而有更多的快乐。

为了好看首先要移除应用的标题栏,将CoreApplicationViewTitleBar.ExtendViewIntoTitleBar属性设置为True:

 
 
Copy
private void ExtendAcrylicIntoTitleBar() { CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; titleBar.ButtonBackgroundColor = Colors.Transparent; titleBar.ButtonInactiveBackgroundColor = Colors.Transparent; }

因为背景是黑色,需要将主题也改为黑色主题,在App.xaml中修改RequestedTheme为Dark:

 
 
Copy
RequestedTheme="Dark"

然后实现MainViewModel。使用到DispatcherTimer进行计时,用DelegateCommand实现命令,这些都只用到WPF的知识:

 
 
Copy
public class MainViewModel: ViewModelBase { public bool IsInPomodoro { get; } public bool IsTimerInProgress { get; } public TimeSpan RemainingBreakTime { get; } public TimeSpan RemainingPomodoroTime { get; } public DelegateCommand StartTimerCommand { get; } public DelegateCommand StopTimerCommand { get; } }

整个UI上就只有4行字,以及停止和开始两个按钮。(上面效果图里还有一个按钮,那是第二版做的)。整个番茄钟由IsInPomodoro和IsTimerInProgress组合成准备开始工作,正在工作,准备休息,正在休息四种状态,MainView上的元素就由IsInPomodoro和IsTimerInProgress这两个属性控制是否显示。

为了用这两个Bool属性控制UI元素的显示和隐藏需要用到Converter,Microsoft.Toolkit.Uwp.UI提供了BoolToVisibilityConverter,我需要再实现一个反过来的NegationBoolToVisibilityConverter:

 
 
Copy
public class NegationBoolToVisibilityConverter : BoolToObjectConverter { public NegationBoolToVisibilityConverter() { base.TrueValue = Visibility.Collapsed; base.FalseValue = Visibility.Visible; } }

这两个Converter配合IsInPomodoro和IsTimerInProgress两个属性用于控制是否显示。然后再使用BoolToObjectConverter定义两个Converter用于控制文字的水平和垂直对齐:

 
 
Copy
converters:BoolToObjectConverter TrueValue="Top" FalseValue="Bottom" x:Key="BoolToVerticalAlignmentConverter" /> converters:BoolToObjectConverter TrueValue="Left" FalseValue="Right" x:Key="BoolToVerticalHorizontalAlignment" />

整个布局大概这样

 
 
Copy
<StackPanel VerticalAlignment="{Binding IsInPomodoro,Converter={StaticResource BoolToVerticalAlignmentConverter}}" HorizontalAlignment="{Binding IsInPomodoro,Converter={StaticResource BoolToVerticalHorizontalAlignment}}"> <TextBlock Text="In Work" Visibility="{Binding IsInPomodoro,Converter={StaticResource BoolToVisibilityConverter}}"/> <TextBlock Text="{Binding RemainingPomodoroTime,Converter={StaticResource FormatStringConverter},ConverterParameter=mm\\:ss}" Visibility="{Binding IsInPomodoro,Converter={StaticResource BoolToVisibilityConverter}}"/> <TextBlock Text="{Binding RemainingBreakTime,Converter={StaticResource FormatStringConverter},ConverterParameter=mm\\:ss}" Visibility="{Binding IsInPomodoro,Converter={StaticResource NegationBoolToVisibilityConverter}}"/> <TextBlock Text="Take a Break" Visibility="{Binding IsInPomodoro,Converter={StaticResource NegationBoolToVisibilityConverter}}"/> </StackPanel> <StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Orientation="Horizontal"> <Button Content="&#xE768;" Visibility="{Binding IsTimerInProgress,Converter={StaticResource NegationBoolToVisibilityConverter}}" Command="{Binding StartTimerCommand}" /> <Button Content="&#xE769;" Visibility="{Binding IsTimerInProgress,Converter={StaticResource BoolToVisibilityConverter}}" Command="{Binding StopTimerCommand}" /> </StackPanel>

到这时候,MainView和MainViewModel几乎只用到WPF的知识,虽然听说DispatcherTimer比较伤性能,也没有用x:Binding代替Binding,主要是想到项目刚开始就尽量用WPF的知识实现所有功能,以后再试用UWP的API。不过动画我倒是没用Storyboard,而是用Composition API做动画。

composition-animation有很多种,我选择使用Windows Community Toolkit中的Implicit Animations,因为它很适合入门。

Implicit Animations(又称为隐式动画)是一种用于描述当属性(例如Opacity or Offset)改变时如何使用动画响应的Composition Animations。而ShowAnimations和HideAnimations分别用于定义当元素显示/隐藏或从VisualTree上添加/移除时的动画效果。

MainView里当状态改变只会引起元素显示/隐藏或者对齐的改变,所以很适合使用隐式动画。例如这段番茄钟倒计时的动画,即显示时从下面200像素向上移动,并且淡入,耗时1.5秒;隐藏时用0.5秒淡出。

 
 
Copy
<animations:Implicit.ShowAnimations> <animations:ScalarAnimation Target="Translation.Y" Duration="0:0:1.5" From="200" To="0" /> <animations:OpacityAnimation Duration="0:0:1.5" From="0" To="1" /> </animations:Implicit.ShowAnimations> <animations:Implicit.HideAnimations> <animations:OpacityAnimation Duration="0:0:0.5" From="1" To="0" /> </animations:Implicit.HideAnimations>

最终动画效果如下:

5. 发布#

就这样一个基本的番茄钟就做好了,之后就是打包和发布。随便画个渐变的背景,再画个圈,Logo就做好了。然后在Package.appxmanifest里处理一下信息,就打包了,就发布了。

官方文档有很详尽的发布指南,微软合作伙伴中心的图形界面也简单易用,稍微折腾一下就可以发布,过几天就可以在Store里见到自己的应用。

每次自己打包都很麻烦,可以将Github仓库(假设有的话)和AppCenter关联起来,每次提交到Github都由AppCenter打安装包。AppCenter打包后即可把安装包下载回来,再发布(话说没有直接帮我发布的方法吗?)

林德熙的这篇文章详细介绍了如何操作。

还可以获得一个徽标,显示编译结果。

Build status

6. 结语#

Edi.Wang被UWP伤害后抛弃了UWP还像个怨念少女那样每天对别人说其实是要说服自己“我才没有喜欢UWP我最讨厌UWP讨厌讨厌最讨厌了”但这样每天每天每天都说UWP是个坏家伙是个坏家伙搞到我反而很想试一试这个坏家伙现在终于忍不了了晚上把switch扔在床上把自己关在书房里亲自动手调教UWP。

总的来说这是个愉快的编程体验:用惯的WPF知识和官方文档,即可实现一个自己用的应用并发布——除了商店偶尔抽风导致自己都下载不了自己的应用外。

顺便一提OnePomodoro的中文名称是一个番茄钟(谢绝对命名品味的一切批评),已经可以在Store下载

最后提一下左下角的按钮。因为1809的Button有了圆角的API,圆形的Reveal按钮很容易实现,只需要BasedOn ButtonRevealStyle再把CornerRadius有那么大就搞那么大:

 
 
Copy
<Style TargetType="Button" x:Key="EllipseButtonRevealStyle" BasedOn="{StaticResource ButtonRevealStyle}"> <Setter Property="CornerRadius" Value="100"/> <Setter Property="Background" Value="Transparent"/> </Style>

这样省去了很多修改ControlTemplate的麻烦,所以项目的最低版本即是1809,反正只是玩玩的东西不要顾虑太多。

7. 如何安装#

可以打开这个链接安装 一个番茄钟,也可以在Microsoft Store中搜索“OnePomodoro”或“一个番茄钟”进行安装。

如果不能安装?我相信,等缘分到了自然可以安装。

8. 参考#

通过《番茄工作法图解》复习番茄工作法

Windows Template Studio quickly builds a UWP app, using a wizard-based UI to turn your needs into a foundation of Windows 10 patterns and best practices

Overview - Visual Studio App Center Microsoft Docs

合成动画 - Windows UWP applications Microsoft Docs

Implicit Animations XAML Attached Properties - Windows Community Toolkit Microsoft Docs

9. 源码#

OnePomodoro

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/11791575.html