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. BZOJ2502:清理雪道(有上下界最小流)

    Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时 ...

  2. InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClas...

    如果 你的项目中使用了注解插件 比如butterknife   升级3.1之后打包编译  出现以下错误提示 InnerClass annotations are missing correspondi ...

  3. PAT B1029 旧键盘 (20 分)

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在 2 行中分别给出应该输入的文字.以及 ...

  4. Python2.7-argparse

    argparse模块,用于方便地编写用户友好的命令行接口,可以自动生成帮助信息,用法信息和错误处理 1.模块对象 1.1 ArgumentParser 对象 1.1.1 初始化构建类:Argument ...

  5. jqgrid 基础应用

    jqgrid 是一个在jquery基础上做的一个表格插件,以ajax的方式和服务器端通信. 一个jqgrid的基础示例(基础参数说明)如下: $("#jqGrid").jqGrid ...

  6. Python操作Saltstack

    1.代码 # -*- coding:utf-8 -*- import urllib.request import urllib.parse import json class saltAPI(): d ...

  7. springboot 定制错误页面

    项目中经常遇到的异常情况 400-Bad Request 401-Unauthorized If the request already included Authorization credenti ...

  8. activiti发布APP时报错:关联的流程无效

    解决办法: 1.检查流程命名和任务命名以及其他命名中是否有特殊字符,有一些字符是不支持的.(中文是可以的,中文标点符号可能不行,我的经验是顿号会报错) 2.检查流程图,把鼠标放到每一根连接线上,观察它 ...

  9. kettle学习笔记(一)——入门与安装

    一.概述 1.kettle是什么 Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,绿色无需安装,数据抽取高效稳定.中文名称叫水壶,该项目的主程序 ...

  10. 20155232《网络对抗》Exp3 免杀原理与实践

    20155232<网络对抗>Exp3 免杀原理与实践 问题回答 1.基础问题回答 (1)杀软是如何检测出恶意代码的? 基于特征码的检测 特征码:一段特征码就是一段或多段数据. 如果一个可执 ...