zoukankan      html  css  js  c++  java
  • 知乎日报win10版

    业余时间写的一个知乎日报win10版客户端,支持收藏,评论,点赞等。

    商店地址:https://www.microsoft.com/zh-cn/store/apps/%E5%A4%A9%E5%A4%A9%E8%AF%BB%E6%8A%A5/9nblggh5fx8z

    开源地址:https://github.com/brookshi/UWP_ZhiHuRiBao 欢迎fork/star。

       

    先上图:

    PC版:

       

    Mobile版:

       

    磁贴:

       

    引用的一系列的库:

    阴影https://github.com/brookshi/XPShadow

    网络https://github.com/brookshi/XPHttp

    列表https://github.com/brookshi/LLMListView

    内部通信https://github.com/brookshi/LLQNotifier

    按钮https://github.com/brookshi/XPButton

    动画https://github.com/brookshi/LLMAnimator

    新浪微博登录http://weibowinrtsdk.codeplex.com/

    API是通过用Fiddler抓取Android版知乎日报获得。

       

    这个应用比较有意思的点:

    1.文章显示

    文章api获取的是一串html,自然想到用webview来显示,不过打开一个文章就用一个webview,占用内存比较大。为解决这个问题,开始尝试将html转成xaml,用RichTextBox显示。用的是: https://github.com/stimulant/SocialStream/blob/master/XAMLConverter/HtmlToXamlConverter.cs

    可惜不能支持所有html节点,而且image显示很慢,字体显示怪异,效果不佳,放弃。

    回到webview,既然是多个webview造成内存大,那只用一个webview不就可以了! 嗯,单例模式。

    每次打开文章时把这个静态的webview单例从Parent中移除,再加到当前Page中。

     1 public static class WebViewUtil
     2     {
     3         static WebViewUtil()
     4         {
     5             _webViewInstance.ScriptNotify += async (s, e) =>
     6             {
     7                 string data = e.Value;
     8                 if (!string.IsNullOrEmpty(data) && data.StartsWith(Html.NotifyPrex))
     9                 {
    10                     await Launcher.LaunchUriAsync(new Uri(data.Substring(Html.NotifyPrex.Length)));
    11                 }
    12             };
    13         }
    14 
    15         private readonly static object _parentLocker = new object();
    16 
    17         private readonly static List<Panel> _webViewParents = new List<Panel>();
    18 
    19         private readonly static WebView _webViewInstance = new WebView();
    20 
    21         public static void AddWebViewWithBinding(Panel parent, object source, string path)
    22         {
    23             Clear();
    24             RemoveParent();
    25             _webViewInstance.SetBinding(WebViewExtend.ContentProperty, new Binding() { Source = source, Path = new PropertyPath(path) });
    26             lock(_parentLocker)
    27             {
    28                 parent.Children.Add(_webViewInstance);
    29                 if (!_webViewParents.Contains(parent))
    30                 {
    31                     _webViewParents.Add(parent);
    32                 }
    33             }
    34         }
    35 
    36         public static void Clear()
    37         {
    38             _webViewInstance.NavigateToString("");
    39         }
    40 
    41         public static bool IsParent(Panel panel)
    42         {
    43             return panel.Children.Contains(_webViewInstance);
    44         }
    45 
    46         public static bool HasParent { get { return _webViewInstance.Parent is Panel; } }
    47 
    48         public static void RemoveParent()
    49         {
    50             lock(_parentLocker)
    51             {
    52                 _webViewParents.ForEach(panel =>
    53                 {
    54                     if (panel.Children.Contains(_webViewInstance))
    55                         panel.Children.Remove(_webViewInstance);
    56                 });
    57             }
    58         }
    59     }
    2.布局

    WinRT支持根据一些条件来显示不同的布局,最常用的就是AdaptiveTrigger,通过设置MinWindowWidth/MinWindowHeight来显示/隐藏元素来展示不同的布局。

    <VisualState>
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="{Binding Source={StaticResource Config}, Path=MinWidth_UIStatus_ListAndContent}" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <Setter Target="StoryContentView.IsPaneOpen" Value="false" />
                            <Setter Target="StoryContentView.DisplayMode" Value="Overlay" />
                        </VisualState.Setters>
                    </VisualState>

    但是有时候条件不单单是Width/Height,还需要其他条件来决定布局,这时可以模仿AdaptiveTrigger创建一个我们自己的StateTrigger。自定义的trigger需要继承StateTriggerBase,加入其他条件ExtraCondition,通过SizeChanged的事件来触发Trigger。

     1  public class AdaptiveTriggerExtended : StateTriggerBase
     2     {
     3         public double MinWindowWidth
     4         {
     5             get { return (double)GetValue(MinWindowWidthProperty); }
     6             set { SetValue(MinWindowWidthProperty, value); }
     7         }
     8         public static readonly DependencyProperty MinWindowWidthProperty =
     9             DependencyProperty.Register("MinWindowWidth", typeof(double), typeof(AdaptiveTriggerExtended), new PropertyMetadata(0));
    10 
    11         public bool ExtraCondition
    12         {
    13             get { return (bool)GetValue(ExtraConditionProperty); }
    14             set { SetValue(ExtraConditionProperty, value); }
    15         }
    16         public static readonly DependencyProperty ExtraConditionProperty =
    17             DependencyProperty.Register("ExtraCondition", typeof(bool), typeof(AdaptiveTriggerExtended), new PropertyMetadata(true));
    18 
    19         private FrameworkElement _targetElement;
    20         public FrameworkElement TargetElement
    21         {
    22             get { return _targetElement; }
    23             set
    24             {
    25                 _targetElement = value;
    26                 _targetElement.SizeChanged += (s, e) => SetActive(ExtraCondition && e.NewSize.Width >= MinWindowWidth);
    27             }
    28         }
    29     }
    3.微博登录

    官方知乎日报登录肯定有自己的AppID和AppSecret,这个不太好找(其实也能找到,把android版日报反编译,细心点就可以找到),不过发现用我自己从微博申请的也可以用。

    官方推荐的win8 SDK,在win10也可以用。

       

    4.Popup Message

    Win10里Toast是把消息发到消息中心,对应用内部提示不是很友好,这里我用Popup模拟了一下android的toast。

    思路是生成一个包含TextBlock的Popup,把要弹出的消息push到一个queue里,按顺序弹出消息,遇到相同的就跳过。

    具体实现代码这里就不贴了,可以参考PopupMessage.cs

       

    其他引用的库如阴影,按钮,列表等就放到后面再写。

  • 相关阅读:
    Phpstorm 换行设置(复制 http://jingyan.baidu.com/article/86fae346b2cb673c49121ad3.html)
    php redis
    php写守护进程(转载 http://blog.csdn.net/tengzhaorong/article/details/9764655)
    进程 、进程组、会话、控制终端之间的关系 (转载 http://blog.csdn.net/yh1548503342/article/details/41891047)
    php等守护进程监控脚本(转载 http://www.9958.pw/post/php_script_scan)
    Http协议与TCP协议简单理解
    php 单线程 (http://bbs.csdn.net/topics/390778072)
    CSS reset
    Vue ref
    Vue 生命周期
  • 原文地址:https://www.cnblogs.com/brookshi/p/5206766.html
Copyright © 2011-2022 走看看