xamarin.forms之实现ListView列表倒计时
做商城类APP时经常会遇到抢购倒计时的功能,之前做小区宝iOS的时候也有类似的功能,想着参考iOS做的思路,自定义一个Cell,在Cell中每秒刷新一下控件的文本值,但使用xamarin.forms实现时,自定义cell的方式并不可行,小伙伴上周给发了一个倒计时功能的demo:https://github.com/jsuarezruiz/MyTripCountdown,demo是如下图实现的是一个时间的倒计时效果,需要将一个倒计时的功能放在列表中,实现多个倒计时的效果, 看了源码也一直没思路,昨天也是没思路报着试一试的心态动手操作了下,没想到成功了,还是非常有成就感的。

一、定义计时器
xamarin.forms提供了Device.StartTimer来实现定时任务,每隔一秒需要触发事件改变剩余时间。这里定义了两个Action,Completed是在倒计时结束时触发,Ticked是每秒触发一次。RemainTime是剩余时间timespan,EndDate为结束时间。
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace TimeCountDown
{
public class CountDown : BindableObject
{
TimeSpan _remainTime;
public event Action Completed;
public event Action Ticked;
public DateTime EndDate { get; set; }
public TimeSpan RemainTime
{
get { return _remainTime; }
private set
{
_remainTime = value;
OnPropertyChanged();
}
}
)
{
Device.StartTimer(TimeSpan.FromSeconds(seconds), () =>
{
RemainTime = (EndDate - DateTime.Now);
;
if (ticked)
{
Ticked?.Invoke();
}
else
{
Completed?.Invoke();
}
return ticked;
});
}
}
}
二、设置BaseViewModel
这里创建了一个BaseViewModel,并有2个方法,LoadAsync()、UnloadAsync(),而且继承了ExtendedBindableObject。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace TimeCountDown
{
public abstract class BaseViewModel : ExtendedBindableObject
{
public virtual Task LoadAsync()
{
return Task.CompletedTask;
}
public virtual Task UnloadAsync()
{
return Task.CompletedTask;
}
}
}
在ExtendedBindableObject中扩展了BindableObject,增加了SetProperty方法,SetProperty方法使用ref引用改变属性的值。
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Xamarin.Forms;
namespace TimeCountDown
{
public class ExtendedBindableObject : BindableObject
{
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName]string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
{
return false;
}
backingStore = value;
OnPropertyChanged(propertyName);
return true;
}
}
}
三、设置ViewModel
新建继承BaseViewModel的类CountDownViewModel,在CountDownViewModel中定义了倒计时类CountDown,当CountDownViewModel调用构造函数时实例化倒计时CountDown,EndDate通过时间戳获得,之后调用LoadAsync()方法,启动计时器,并为计时器绑定具体Actio,在Ticked的Action中每秒定时刷新绑定到界面的数值。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace TimeCountDown
{
public class CountDownViewModel : BaseViewModel
{
public long Tick { get; set; }
private string _countDownTitle;
public string CountDownTitle
{
get => _countDownTitle;
set => SetProperty(ref _countDownTitle, value);
}
private CountDown _countDown;
public CountDownViewModel(long ticks)
{
Tick = ticks;
_countDown = new CountDown() { EndDate = DateTime.Now.Add(new TimeSpan(ticks)) };
LoadAsync();
}
public override Task LoadAsync()
{
_countDown.Start();
_countDown.Ticked += OnCountdownTicked;
_countDown.Completed += OnCountdownCompleted;
return base.LoadAsync();
}
public override Task UnloadAsync()
{
_countDown.Ticked -= OnCountdownTicked;
_countDown.Completed -= OnCountdownCompleted;
return base.UnloadAsync();
}
void OnCountdownTicked()
{
CountDownTitle = string.Format("{0}:{1}:{2}后开抢", _countDown.RemainTime.Hours, _countDown.RemainTime.Minutes, _countDown.RemainTime.Seconds);
}
void OnCountdownCompleted()
{
CountDownTitle = "抢购进行中";
UnloadAsync();
}
}
}
四、测试
在MainPage中设置了一个ListView,ViewCell模板中设置了一个Label,Text值绑定了CountDownTitle。在MainPage的构造方法中设置listview的ItemsSource。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TimeCountDown"
x:Class="TimeCountDown.MainPage">
<StackLayout>
<ListView x:Name="listView" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text=" TextColor="Black" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
public MainPage()
{
InitializeComponent();
List<CountDownViewModel> countDownVMs = new List<CountDownViewModel>() {
),
),
),
),
};
listView.ItemsSource = countDownVMs;
}
效果图如下:


xamarin.forms之实现ListView列表倒计时的更多相关文章
- Xamarin.Forms中的ListView的ItemTrapped事件与ItemSelected事件的区别
今天对Xamarin.Forms中的ListView的两个事件(ItemTrapped和ItemSelected)做了小小的研究,发现有以下几点区别: 1.ItemTrapped事件会优先被触发. 2 ...
- A Xamarin.Forms Infinite Scrolling ListView
from:http://www.codenutz.com/lac09-xamarin-forms-infinite-scrolling-listview/ The last few months ha ...
- Xamarin自定义布局系列——ListView的一个自定义实现ItemsControl(横向列表)
在以前写UWP程序的时候,了解到在ListView或者ListBox这类的列表空间中,有一个叫做ItemsPannel的属性,它是所有列表中子元素实际的容器,如果要让列表进行横向排列,只需要在Xaml ...
- Xamarin.Forms: 无限滚动的ListView(懒加载方式)
说明 在本博客中,学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView.这个无限滚动函数在默认的Xamarin.Forms不存在,因此我们需要为此添加插件.在这里我 ...
- Xamarin.Forms 简介
An Introduction to Xamarin.Forms 来源:http://developer.xamarin.com/guides/cross-platform/xamarin-forms ...
- 老司机学新平台 - Xamarin Forms开发框架之MvvmCross插件精选
在前两篇老司机学Xamarin系列中,简单介绍了Xamarin开发环境的搭建以及Prism和MvvmCross这两个开发框架.不同的框架,往往不仅仅使用不同的架构风格,同时社区活跃度不同,各种功能模块 ...
- Xamarin.Forms入门-使用 Xamarin.Forms 来创建跨平台的用户界面
Xamarin.Forms 是一个跨平台的.基于原生控件的UI工具包,开发人员可以轻松的创建适用于 Android,iOS 以及 Windows Phone的用户界面.Xamarin.Forms 通过 ...
- 张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )
所谓 UWP 样式的汉堡菜单,我曾在"张高兴的 UWP 开发笔记:汉堡菜单进阶"里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色 ...
- xamarin.forms之page
最近在使用xamarin.forms做APP开发,之前做过ios的应用,虽然没做过安卓,但之前也有一点了解,什么四大组件五大布局啥的,微软的xamarin.forms的文档也挺详细的,基本都是复制粘贴 ...
随机推荐
- ubuntu/deepin 下 Sha 哈 dow 哈 socks 全局配置
1. 安装编译环境 Ubuntu在默认情况下没有提供C/C++的编译环境,因此需要手动安装.如果单独安装gcc以及g++比较麻烦,为了方便,我们直接安装Ubuntu提供的build-essential ...
- TypeError: a bytes-like object is required, not 'str'
python bytes和str两种类型转换的函数encode(),decode() str通过encode()方法可以编码为指定的bytes 反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数 ...
- mysql8.0.13修改密码
在安装完数据库后,由于自己不小心直接关闭了安装窗口,或者长时间没有使用root用户登录系统,导致忘记了root密码,这时就需要重置MySQL的root密码.当然,最简单方式自然是删除数据库的data目 ...
- Java内存模型锦集
[内存操作与内存屏障] 内存模型操作: lock(锁定) : 作用与主内存的变量, 它把一个变量标识为一条线程独占的状态 unlock(解锁) : 作用于主内存变量, 它把一个处于锁定状态的变量释放出 ...
- HelloPython
HELLOWORD!你好!Python! 学习Python已有一段时间,一个人自学颇不容易,在此分享一些自己学习经验和感受,温故而知新,也希望自己能有些新收获. 学习Python,大多数人创建的第一个 ...
- Swift 编程杂谈
1.Swift 3.0 使用Cocopods 导入第三方报错 之前一直用Object-C 编写代码 用Cocopods导入第三方没出过什么问题(PS:2017最新cocoaPods安装教程) 今天用 ...
- FCC(ES6写法) Friendly Date Ranges
把常见的日期格式如:YYYY-MM-DD 转换成一种更易读的格式. 易读格式应该是用月份名称代替月份数字,用序数词代替数字来表示天 (1st 代替 1). 包含当前年份和相同月份的时候,makeFri ...
- LeetCode编程训练 - 合并查找(Union Find)
Union Find算法基础 Union Find算法用于处理集合的合并和查询问题,其定义了两个用于并查集的操作: Find: 确定元素属于哪一个子集,或判断两个元素是否属于同一子集 Union: 将 ...
- Android 音视频开发(六): MediaCodec API 详解
在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...
- macOS 10.14虚拟机安装教程
windows10下安装vmware14.0以及macOS 10.14图文详解 工具/原料 windows10 vmware 14.0 macOS 10.14懒人版 mac补丁unlocker工具 ...