从OpenWeen到Tuuto,改变了什么

OpenWeen和Tuuto,两款功能定位十分相似,界面也有很多相同之处,但是其内部的设计却有所不同。

简单来说,再OpenWeen踩过坑之后,Tuuto的耦合性更低,各方面的维护和修改会变得更加的简单

同时也意识到了我是一个懒人,同样功能,代码写的越少越开心(

首先从各种自定义控件开始说起

FixedPivot控件

两者共同拥有的一个效果,就是主页面的Pivot视图会随着大小的改变而改变Header的位置/大小。

默认的Pivot是固定的Header而且宽度不会随着大小的改变而改变,很不优雅,想要用默认Pivot设计好界面不是很容易。

OpenWeen是把Pivot作为页面上的一个控件,通过代码关闭自带的Header之后,再通过AdaptiveTrigger设置属性显示自定义的Header和SplitView的Pane,而Header不是通过PivotItem获取的,而是还需要写代码定义一个Header的列表,再将自定义Header和SplitView的Pane绑定到列表,而且还需要绑定SelectedIndex到Pivot上。

也许描述的不是太好有点难以理解,总之,如果需要修改Pivot内容,比如有一个PivotItem不需要了,除了把它删掉,还需要修改别的地方,牵一发而动全身,不仅在定义Pivot时需要写很多代码,在使用的时候还需要写比较多的代码,很麻烦。

而在Tuuto中,这样的情况得到了彻底的解决,FixedPivot作为单独的控件,不再与其他内容有关联,只需要简单的调用即可,同时在内部处理了更多的操作,比如双击Header刷新,单击Header返回顶部,不再需要再在Page里单独处理。

关于实现,简单的说就是将原先置于Pivot外的Header和SplitView添加到Pivot的Template内,定义一个FixedPivotItem来解决对Header Icon和文字的定义和读取。但是出现了当SplitView的Pane显示时PivotItemPresenter会在右侧超出控件范围,也就是右侧会有一部分内容会被挡住看不到。目前暂时只能手动计算PivotItemPresenter的尺寸,希望之后能有个更好的解决方法。

Xaml , 代码

MediaViewDialog

查看图片都是以Dialog的方式实现的,但是其中实现全屏Dialog的方式却有所不同

在OpenWeen里面,是通过注册Window.Current.SizeChanged事件来动态计算并更新Dialog和Image的尺寸,虽然是一种解决方法,但是这种如果不小心处理就会产生问题,毕竟Window.Current.SizeChanged是整个窗口的事件,需要在Dialog关闭的时候取消注册。整个实现并不是很理想。

Tuuto里面,则是使用自定义Style,通过Setter绑定到自身ActualHeight/ActualWidth,然后在Template里将默认的Margin/Padding设为0,这样得到了一个全屏的Dialog,比起之前,这样的实现会更加理想。

列表ListView

同样都是需要列表显示的内容,OpenWeen是通过自定义ItemsControl实现,然后通过DataTemplateSelector来选择对应的DataTemplate,然后在自定义的ListView内处理各种事件。与其说是处理,不如说是再Invoke新的事件罢了。这样的实现也不是很理想,虽然不是牵一发而动全身,但是对于各种事件的处理仍然需要写很多重复代码,一些基本的事件处理,比如转发、评论、点赞,这些事件基本上都只会有一种操作,而且这些事件不应该由ListView处理/Invoke。

在Tuuto中,自定义ListView继承自UWPCommunityToolkit内的PullToRefreshListView,并且添加了空白显示和错误显示,去除了不应该在ListView内处理的一系列事件,现在这个ListView就是存粹的ListView,各种事件的处理被放到了StatusView内,由StatusView进行处理。像诸如转发、回复、点赞、用户详情等这样的事件就不会产生重复代码。空白项是通过注册ListView的Items.VectorChanged事件,检测Items是否为空实现。

在载入更多的时候,两者的实现也完全不同。OpenWeen是通过监听ScrollViewer.ViewChanged事件,让到达底部时出发LoadMore事件,让ViewModel去载入更多。这样的实现虽然说比较常用,但是并不是很方便的实现。

在Tuuto中,充分利用了ListView可以使用ISupportIncrementalLoading作为数据源来实现自动载入,使用UWPCommunityToolkit的IIncrementalSource,配合IncrementalLoadingCollection,可以轻松简单的实现上面同样的功能,只需要在继承了IIncrementalSource内编写载入数据代码,ViewModel内放置IncrementalLoadingCollection数据源,ListView绑定即可,再也不用手写Refresh或者LoadMore。

富文本处理

OpenWeen和Tuuto都是需要对微博/嘟嘟内容进行富文本处理,虽然最终的效果基本相同,但是实现的方式却大相径庭,这大概是因为API返回的差别所造成的。
微博的API返回的就是纯文本,需要自行识别哪一些需要进行处理。而Mastodon的API返回的HTML,相比需要自行识别需要处理的文本来说,HTML已经为我们指出了哪些文本需要进行处理。
OpenWeen使用正则匹配然后替换字符串,方法比较原始。
Tuuto是通过将HTML转换为Markdown,再通过UWPCommunityToolkit的MarkdownTextBlock显示。相比原始的正则匹配替换,这样的方法更加准确,成功率更高。

发送微博/嘟嘟

再发送的处理上,OpenWeen和Tuuto的处理完全不同。
OpenWeen是让用户再发送页面等待,如果发送成功了自动退出,不成功会仍然停留再发送页面。这样的体验并不是很好,在网速慢一些的情况下会发送很久,但是用户并不会想一直看着发送页面,用户希望能够返回到浏览页面。
Tuuto便是这样处理的,在用户发送之后,便立即返回浏览页面,发送请求通过DraftManager处理,先通过Entity Framework Core将发送内容保存到SQLite中,然后执行发送,如果成功了将本地数据库中保存的内容删除,失败了就更新失败信息,然后为用户显示一个通知,告诉用户当前是否发送成功了。如果失败了,用户可以在发送页面可以选择载入对应的草稿。
还有其他的一些地方有所不同,就不一一列举了,每一次踩坑都是为了下一次更优雅的踩坑,虽然有想法利用Tuuto里面的成果重写一遍OpenWeen,但是微博关闭平台并不是很乐观,第三方客户端似乎随时都可能死亡,所以现在也没有太多动力去重写。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据