Toast简介

在安卓里Toast是内置原生支持,它是Android中用来显示显示信息的一种机制。它主要用于向用户显示提示消息,没有焦点,显示的时间有限,过一定的时间就会自动消失。在UWP中虽然没有原生支持的Toast,但是完全可以用Popup封装实现一个简单的Toast自定义控件。

Toast效果图

先上效果图:

上面是最终要做的效果图,从动态图中我们一点一点分析一下Toast是怎样做出来的。

  • 首先,我们可以明显看出它是有渐显效果。想要让它不是突兀地显示出来,而是慢慢显示出来,我们就要用到StoryBoard来做显示的动画。
  • 其次,Toast的控件构成上是由一个带背景色的Grid加一个垂直居中的TextBlock组合而成。
  • 最后,既然是要将它封装成一个用户控件,而在不同场景中Toast显示的文字提示肯定也不一样,所以我们还需要使用依赖属性DependcyProperty为它指定对应的消息。

Toast的实现

在实现上,由于Popup与Toast非常相似,都是只需要在必要的时候弹出来,所以我们这里以Popup作为主体来改造成我们需要的Toast。首先我们新建一个User Control,叫Toast.xaml即可。新建的方法如下图:

控件布局

Popup的Border可以从效果图中非常轻易地看出来,一个Background为Black的半透明Grid + 一个不透明的白色字TextBlock就可以帮我们解决问题,代码如下:

<UserControl
x:Class="Course.Controls.ToastPrompt"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Course.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Popup x:Name="Toast">
<Border>
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
MinHeight="100"
MinWidth="300">
<!--这里为了不让Textblock的字Opacity保持100%,我们只对Grid的Border设置Opacity和Background即可-->
<Border Background="Black"
Opacity="0.6"
HorizontalAlignment="Stretch"
CornerRadius="4"/>
<Grid VerticalAlignment="Center"
Margin="30">
<TextBlock x:Name="textBlockMsg"
MinWidth="150"
TextWrapping="Wrap"
Text="{Binding Label}"
Foreground="#FFFFFFFF"/>
</Grid>
</Grid>
</Border>
</Popup>
</UserControl>

动画效果

为了做出渐显和渐隐的效果,我们需要使用Storyboard中的DoubleAnimation(应该是叫线性动画)。它指定一个Double类型的属性,可以使其在指定的时间内由起点值到达终点值,从而形成动画效果。

这里改变的Double类型的属性是控件的Opacity(透明度)。这里我们可以用指定动画中的关键帧与出现的时间、属性,之后后台会自动帮我们进行线性插值计算,达到最终的效果。下面是动画效果部分的代码。

<UserControl.Resources>
<Storyboard x:Name="StoryboardShowPopup">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="Toast">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<!--这里的0:0:0.2是关键帧在时间轴上的位置-->
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="StoryboardHiddenPopup">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="Toast">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>

后台逻辑

在写完控件和动画的部分后,我们来做一下后台的逻辑。后台的逻辑按照我们上面的表述,要包括两部分:

  • 依赖属性,用于从外部传递要显示的消息内容。
  • Toast的显示函数:弹出Toast,开始播放显示动画,停顿一会,开始播放隐藏动画,动画完成后Toast关闭。

为了达到动画完成后Toast关闭这一点,我们需要在上面的Storyboard中小小地加一句,添加在这里:

    <Storyboard x:Name="StoryboardHiddenPopup" Completed="StoryboardHiddenPopup_Completed" .../>

这段代码的意思是指,当StoryboardHiddenPopup动画结束后,自动执行函数StoryboardHiddenPopup_Completed。其他逻辑的实现代码如下:

    public sealed partial class Toast : UserControl
{
//这段代码是通用的依赖属性定义代码,为控件自定义了一个名为Label的属性。
public DependencyProperty LabelProperty =
DependencyProperty.Register("Label", typeof(string), typeof(ToastPrompt), null); //这一段代码将变量Label和Label依赖属性绑定在了一起,从而可以通过Binding到Label变量来间接绑定到依赖属性LabelProperty。
public string Label
{
get { return GetValue(LabelProperty) as string; }
set { SetValue(LabelProperty, value); }
} public ToastPrompt()
{
this.InitializeComponent();
this.DataContext = this;
} public async Task Show()
{
this.Toast.IsOpen = false;
this.StoryboardHiddenPopup.Stop();
this.StoryboardShowPopup.Stop();
//这三步是为了清除上一次动画的效果
this.Toast.IsOpen = true;
this.StoryboardShowPopup.Begin();
//内容提示停留1.2s后开始隐藏
await Task.Delay(1200);
this.StoryboardHiddenPopup.Begin();
} //当隐藏动画播放结束后会自动调用StoryboardHiddenPopup_Completed
private void StoryboardHiddenPopup_Completed(object sender, object e)
{
this.Toast.IsOpen = false;
}
}

写完了前后台逻辑,下面来讲一下如何使用这个Toast控件。

Toast的使用

使用Toast也非常简单,就像使用普通的UserControl一样,前台在xxx.xaml 的某个容器中定义好即可,比如下面这段:

<Grid>
<local:ToastPrompt
x:Name="LoginToast"
Width="300"
Height="150"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Label ="{x:Bind ViewModel.Message,Mode=OneWay}"/>
</Grid>

随后将Label(这个就是我们自定义的依赖属性)绑定到页面ViewModel(MVVM模式)中的某个变量上即可,这样更改ViewModel中的Message,Toast中的消息也会跟着变化。

需要Toast出现的时候,只需要在后台逻辑里调用Show方法即可,比如下面这段代码:

public async void Login(){
...
this.LoginToast.Show();
...
}

如果不同的Toast需要停留的时间不一样长,可以考虑使用DispatcherTimer来控制Toast显示的时间。

【UWP开发】一个简单的Toast实现的更多相关文章

  1. [UWP 开发] 一个简单的Toast实现

    Toast简介 在安卓里Toast是内置原生支持,它是Android中用来显示显示信息的一种机制.它主要用于向用户显示提示消息,没有焦点,显示的时间有限,过一定的时间就会自动消失.在UWP中虽然没有原 ...

  2. 如何开发一个简单的HTML5 Canvas 小游戏

    原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...

  3. 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务

    [源码下载] 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后 ...

  4. Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状)

    Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状) 本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏-记数字踩白块. 游戏的流程是这种:在界面上生成5个数1~5字并显 ...

  5. Python开发一个简单的BBS论坛

    项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...

  6. 作业1开发一个简单的python计算器

    开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...

  7. django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面

    1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...

  8. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  9. 【UI插件】开发一个简单日历插件(上)

    前言 最近开始整理我们的单页应用框架了,虽然可能比不上MVVM模式的开发效率,也可能没有Backbone框架模块清晰,但是好歹也是自己开发出来 而且也用于了这么多频道的东西,如果没有总结,没有整理,没 ...

随机推荐

  1. 第一章-第十三题(该游戏团队, 有很好的软件,但是商业模式和其他软件之外的因素有没有考虑到?)--By梁旭晖

    这款软件无疑是一个好软件,软件的开发者是有相当水平的,可以说是优秀的软件编写人员,但是也只是优秀的软件人员,术业有专攻,他们在其他方面我觉得是有很大的欠缺的. 我觉得,他们并没有抓住消费者的心理,首先 ...

  2. C++类型转换函数

    1.什么是类型转换函数 类型转换函数的作用是将一个类的对象转换成另一类型的数据. class testclass { private: int r; int m; public : testclass ...

  3. ListView.setAdapter(adapter);空指针异常的解决的总结

    报空指针异常一般的情况: 1,没有找到布局文件的ID  检验是不是id重复或者写错了 2.控件没有实例化 3.没有找到布局文件的id,要看看是不是加载了布局了,必须加载了对应的布局才能找到对应布局下的 ...

  4. 详解Maple中的基础工具栏

    鉴于Maple 强大的符号计算功能,越来越多的人选择使用Maple 2015计算复杂的数学问题,初学者刚开始时需要对Maple有所熟悉才能很好地进行运用,下面就从基础开始,介绍Maple工作环境. M ...

  5. c++ eof()函数

    C++ eof()函数可以帮助我们用来判断文件是否为空,抑或是判断其是否读到文件结尾.在这里我们将会对其进行详细的介绍. C++编程语言中的很多功能在我们的实际应用中起着非常大的作用.比如在对文件文本 ...

  6. 循序渐进做项目系列(4)迷你QQ篇(2)——视频聊天!(附源码)

    一·效果展示 源码派送:MiniQQ1.1 文字聊天的实现参见:循序渐进做项目系列(3):迷你QQ篇(1)——实现客户端互相聊天 二·服务端设计 对于实现视频聊天而言,服务端最核心的工作就是要构造多媒 ...

  7. .NET中使用APlayer组件自制播放器

    目录 说明 APlayer介绍 APlayer具备功能 APlayer使用 自制播放器Demo 未完成工作 源码下载 说明 由于需求原因,需要在项目中(桌面程序)集成一个在线播放视频的功能.大概要具备 ...

  8. JavaScript多文件下载

    对于文件的下载,可以说是一个十分常见的话题,前端的很多项目中都会有这样的需求,比如 highChart 统计图的导出,在线图片编辑中的图片保存,在线代码编辑的代码导出等等.而很多时候,我们只给了一个链 ...

  9. 【Java并发编程实战】-----“J.U.C”:Condition

    在看Condition之前,我们先来看下面这个例子: 工厂类,用来存放.取出商品: public class Depot { private int depotSize; //仓库大小 private ...

  10. CSharpGL(1)从最简单的例子开始使用CSharpGL

    CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...