listview刷新_Xamarin.Forms之实现ListView列表倒计时

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

5c08c434f2cbe58e9d047238d882ba3a.png

一、定义计时器

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();
}
}public void Start(int seconds = 1)
{
Device.StartTimer(TimeSpan.FromSeconds(seconds), () =>
{
RemainTime = (EndDate - DateTime.Now);var ticked = RemainTime.TotalSeconds > 1;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(ref T backingStore, T value, [CallerMemberName]string propertyName = "")
{if (EqualityComparer.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" ?>"http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TimeCountDown"
x:Class="TimeCountDown.MainPage">"listView" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">"{Binding CountDownTitle}" FontSize="14" TextColor="Black" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        public MainPage()
{
InitializeComponent();
List countDownVMs = new List() {new CountDownViewModel(11111111111),new CountDownViewModel(2222222222),new CountDownViewModel(3333333333333),new CountDownViewModel(444444444444),
};
listView.ItemsSource = countDownVMs;
}

效果图如下:

5aaaeaa75d461476662cc59166edd901.png

7acc8a51e14fd5e8e6d54d0ac01be8f3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值