<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>爱红旗渠</title>
  
  <subtitle>Stay hungry, stay foolish.</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://94275.cn/"/>
  <updated>2024-06-15T15:24:16.181Z</updated>
  <id>http://94275.cn/</id>
  
  <author>
    <name>Jin</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>前端十年变迁史</title>
    <link href="http://94275.cn/2019/11/20/fe-2008-2017/"/>
    <id>http://94275.cn/2019/11/20/fe-2008-2017/</id>
    <published>2019-11-20T08:10:28.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><a id="more"></a><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><h3 id="前端标准发展史"><a href="#前端标准发展史" class="headerlink" title="前端标准发展史"></a>前端标准发展史</h3><p><img src="https://ppt.94275.cn/assets/images/fe/前端标准迭代历史.png" alt="前端标准迭代历史"></p><h3 id="分享主要内容"><a href="#分享主要内容" class="headerlink" title="分享主要内容"></a>分享主要内容</h3><ol><li>原始社会</li><li>石器时代</li><li>铁器时代</li><li>工业时代</li><li>前端拓展</li></ol><h2 id="1-原始社会"><a href="#1-原始社会" class="headerlink" title="1. 原始社会"></a>1. 原始社会</h2><h3 id="1-1-图示"><a href="#1-1-图示" class="headerlink" title="1.1 图示"></a>1.1 图示</h3><p><img src="https://ppt.94275.cn/assets/images/fe/原始社会.jpeg" alt="原始社会"></p><h3 id="1-2-形象"><a href="#1-2-形象" class="headerlink" title="1.2 形象"></a>1.2 形象</h3><p><img src="https://ppt.94275.cn/assets/images/fe/原始社会-形象图.jpeg" alt="原始社会-形象图"></p><h3 id="1-3-主要特征"><a href="#1-3-主要特征" class="headerlink" title="1.3 主要特征"></a>1.3 主要特征</h3><ol><li>响应时间较长，小操作都需要刷整个页面</li><li>页面简陋</li></ol><h3 id="1-4-重要元素"><a href="#1-4-重要元素" class="headerlink" title="1.4 重要元素"></a>1.4 重要元素</h3><ol><li>1990 年 Netscape 浏览器</li><li>1991 年 WWW 诞生</li><li>1994 W3C 成立</li></ol><h2 id="2-石器时代"><a href="#2-石器时代" class="headerlink" title="2. 石器时代"></a>2. 石器时代</h2><h3 id="2-1-图示"><a href="#2-1-图示" class="headerlink" title="2.1 图示"></a>2.1 图示</h3><p><img src="https://ppt.94275.cn/assets/images/fe/石器时代.jpeg" alt="石器时代"></p><h3 id="2-2-形象图"><a href="#2-2-形象图" class="headerlink" title="2.2 形象图"></a>2.2 形象图</h3><p><img src="https://ppt.94275.cn/assets/images/fe/石器社会-钻木取火-形象图.jpeg" alt="石器时代-形象图"></p><h3 id="2-3-主要特征"><a href="#2-3-主要特征" class="headerlink" title="2.3 主要特征"></a>2.3 主要特征</h3><ol><li>页面还是需要整体刷新</li><li>页面变漂亮了</li><li>HTML 为骨架，CSS 为外貌，Java 为交互。</li></ol><h3 id="2-4-重要元素"><a href="#2-4-重要元素" class="headerlink" title="2.4 重要元素"></a>2.4 重要元素</h3><ol><li>PHP/JSP/ASP.NET</li><li>CSS</li></ol><h2 id="3-铁器时代"><a href="#3-铁器时代" class="headerlink" title="3. 铁器时代"></a>3. 铁器时代</h2><h3 id="3-1-图示"><a href="#3-1-图示" class="headerlink" title="3.1 图示"></a>3.1 图示</h3><p><img src="https://ppt.94275.cn/assets/images/fe/铁器时代.png" alt="铁器时代"></p><h3 id="3-2-形象"><a href="#3-2-形象" class="headerlink" title="3.2 形象"></a>3.2 形象</h3><p><img src="https://ppt.94275.cn/assets/images/fe/铁器社会-形象图.jpeg" alt="铁器社会-形象图"></p><h3 id="3-3-主要特征"><a href="#3-3-主要特征" class="headerlink" title="3.3 主要特征"></a>3.3 主要特征</h3><ol><li>支持异步请求，不用刷整个页面(Ajax 1998 创建-2006 纳入W3C)</li><li>前端不再是模板</li><li>HTML 为骨架，CSS 为外貌，Java和 JavaScript 为交互。</li></ol><h3 id="3-4-重要元素"><a href="#3-4-重要元素" class="headerlink" title="3.4 重要元素"></a>3.4 重要元素</h3><ol><li>浏览器兼容</li><li>Ajax</li><li>jQuery</li></ol><h2 id="4-工业时代"><a href="#4-工业时代" class="headerlink" title="4. 工业时代"></a>4. 工业时代</h2><h3 id="4-1-图示"><a href="#4-1-图示" class="headerlink" title="4.1 图示"></a>4.1 图示</h3><p><img src="https://ppt.94275.cn/assets/images/fe/工业时代.png" alt="工业时代"></p><h3 id="4-2-形象图"><a href="#4-2-形象图" class="headerlink" title="4.2 形象图"></a>4.2 形象图</h3><h3 id="4-3-主要特征"><a href="#4-3-主要特征" class="headerlink" title="4.3 主要特征"></a>4.3 主要特征</h3><ol><li>页面变得越来越复杂</li><li>对用户体验要求越来越高</li><li>前端开发变立体</li><li>模块化/工程化</li><li>技术后端化(MVVM，nginx，lua)</li><li>后端微服务 / 前端更多业务逻辑</li></ol><h3 id="4-4-重要元素"><a href="#4-4-重要元素" class="headerlink" title="4.4 重要元素"></a>4.4 重要元素</h3><ol><li>Angular/React/Vue</li><li>MVVM</li><li>前端更多的原生能力</li><li>HTML5</li><li>CommonJS / AMD(requireJS) / CMD(SeaJS) / ES6</li></ol><h3 id="4-5-相对铁器时代变化"><a href="#4-5-相对铁器时代变化" class="headerlink" title="4.5 相对铁器时代变化"></a>4.5 相对铁器时代变化</h3><p><img src="https://ppt.94275.cn/assets/images/fe/前端架构变化.png" alt="相对铁器时代变化"></p><h2 id="5-前端拓展"><a href="#5-前端拓展" class="headerlink" title="5. 前端拓展"></a>5. 前端拓展</h2><h3 id="5-1-浏览器近代史"><a href="#5-1-浏览器近代史" class="headerlink" title="5.1 浏览器近代史"></a>5.1 浏览器近代史</h3><h4 id="5-1-1-全球浏览器"><a href="#5-1-1-全球浏览器" class="headerlink" title="5.1.1 全球浏览器"></a>5.1.1 全球浏览器</h4><p><img src="https://ppt.94275.cn/assets/images/fe/StatCounter-browser-all-200901-201909.png" alt="全世界浏览器占比"></p><h4 id="5-1-2-全球浏览器M"><a href="#5-1-2-全球浏览器M" class="headerlink" title="5.1.2 全球浏览器M"></a>5.1.2 全球浏览器M</h4><p><img src="https://ppt.94275.cn/assets/images/fe/StatCounter-browser-m-200901-201909.png" alt="全世界浏览器占比m"></p><h4 id="5-1-3-中国浏览器"><a href="#5-1-3-中国浏览器" class="headerlink" title="5.1.3 中国浏览器"></a>5.1.3 中国浏览器</h4><p><img src="https://ppt.94275.cn/assets/images/fe/StatCounter-browser-CN-all-200901-201909.png" alt="中国浏览器占比"></p><h4 id="5-1-4-中国浏览器M"><a href="#5-1-4-中国浏览器M" class="headerlink" title="5.1.4 中国浏览器M"></a>5.1.4 中国浏览器M</h4><p><img src="https://ppt.94275.cn/assets/images/fe/StatCounter-browser-CN-m-200901-201909.png" alt="中国浏览器占比"></p><h3 id="5-2-前端知识体系"><a href="#5-2-前端知识体系" class="headerlink" title="5.2 前端知识体系"></a>5.2 前端知识体系</h3><p><a href="https://www.processon.com/view/5d92f0a9e4b0e26dddaed714?fromnew=1#map" rel="external nofollow noopener noreferrer" target="_blank"><img src="https://ppt.94275.cn/assets/images/fe/Web前端知识提起-概要.png" alt="Web前端知识体系"></a></p><h3 id="5-3-从前端走向全端"><a href="#5-3-从前端走向全端" class="headerlink" title="5.3 从前端走向全端"></a>5.3 从前端走向全端</h3><ol><li>node</li><li>react native</li><li>小程序</li><li>PWA</li><li>…</li></ol><p><img src="https://ppt.94275.cn/assets/images/fe/前端发展史二维码.png" alt="前端发展史二维码"></p><p><br>本文地址 <a href="http://94275.cn/2019/11/20/fe-2008-2017/">http://94275.cn/2019/11/20/fe-2008-2017/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Spring MVC 学习指南</title>
    <link href="http://94275.cn/2019/02/07/Spring-MVC/"/>
    <id>http://94275.cn/2019/02/07/Spring-MVC/</id>
    <published>2019-02-07T12:38:34.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>近日读《Spring MVC 学习指南》，对 Spring MVC 有了更深一些的了解。</p><a id="more"></a><p>主要包含以下几个方面：Spring MVC 框架、模式2和 MVC 模式、Spring MVC 介绍、基于注解的控制器、数据绑定和表单标签库、转换器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件。</p><p><img src="/imgs/post/spring_mvc_mindmap.png" alt="Spring MVC 学习指南"></p><p>希望本图对你有所帮助。源图连接地址：<a href="https://www.processon.com/view/5c541629e4b048f108e44c20" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/view/5c541629e4b048f108e44c20</a></p><p><br>本文地址 <a href="http://94275.cn/2019/02/07/Spring-MVC/">http://94275.cn/2019/02/07/Spring-MVC/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;近日读《Spring MVC 学习指南》，对 Spring MVC 有了更深一些的了解。&lt;/p&gt;
    
    </summary>
    
      <category term="Spring" scheme="http://94275.cn/categories/Spring/"/>
    
    
      <category term="Spring MVC" scheme="http://94275.cn/tags/Spring-MVC/"/>
    
  </entry>
  
  <entry>
    <title>Effective JavaScript 提高代码质量的68个有效方法</title>
    <link href="http://94275.cn/2019/02/01/Effective-JavaScript/"/>
    <id>http://94275.cn/2019/02/01/Effective-JavaScript/</id>
    <published>2019-02-01T15:20:01.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>近日，读《Effective JavaScript-编写高质量 JavaScript 代码的68个有效方法》，感觉很实用很不错，特整理出书中的68个方法的思维导图。</p><a id="more"></a><p>脑图如下：</p><p><img src="/imgs/post/javascript_68_mindmap.png" alt="68个提高代码质量的方法"></p><p>原版在 <a href="https://www.processon.com/i/5467870be4b054d6db9d9ad8" rel="external nofollow noopener noreferrer" target="_blank">ProcessOn</a> 上创作，需要原版思维脑图请访问：<a href="https://www.processon.com/view/link/5c5464fbe4b0fa03cead9989" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/view/link/5c5464fbe4b0fa03cead9989</a></p><p>ProcessOn 注册地址：<a href="https://www.processon.com/i/5467870be4b054d6db9d9ad8" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/i/5467870be4b054d6db9d9ad8</a></p><p><br>本文地址 <a href="http://94275.cn/2019/02/01/Effective-JavaScript/">http://94275.cn/2019/02/01/Effective-JavaScript/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;近日，读《Effective JavaScript-编写高质量 JavaScript 代码的68个有效方法》，感觉很实用很不错，特整理出书中的68个方法的思维导图。&lt;/p&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://94275.cn/categories/JavaScript/"/>
    
    
      <category term="JavaScript" scheme="http://94275.cn/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>微信小程序之分享到朋友圈</title>
    <link href="http://94275.cn/2018/11/19/wxminiapp-canvas/"/>
    <id>http://94275.cn/2018/11/19/wxminiapp-canvas/</id>
    <published>2018-11-19T08:03:20.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>微信小程序目前仅支持分享给好友，暂不支持直接分享到朋友圈。针对分享到朋友圈这个问题，通常的做法是生成一张海报图片然后把图片分享到朋友圈。朋友圈到我们的小程序，通过长按图片识别图中小程序码实现。<img src="https://img.shields.io/badge/wx-canvas-green.svg" alt="WX Canvas"></p><a id="more"></a><h3 id="1-基本介绍"><a href="#1-基本介绍" class="headerlink" title="1. 基本介绍"></a>1. 基本介绍</h3><p>本代码库是微信小程序的一个每日分享案例。每天会中英文美句，推荐给大家，可以点击保存图片到本地，然后分享到朋友圈（小程序暂不支持直接分享到朋友圈）。主要用到的技术点就是 canvas 画图。</p><p><img src="https://github.com/jingle1267/HelloCodeDev/raw/master/doc/gh_4d67d640e67d_430.jpg" alt="洪谷山小程序码"></p><p>欢迎微信扫码体验，有任何问题可以提意见反馈。谢谢！</p><p>效果图如下：<br><img src="https://github.com/jingle1267/HelloCodeDev/blob/master/doc/WechatIMG21163.png?raw=true" alt="小程序预览图"></p><p>如果对小程序不太了解的话，可以先看我的小程序入门介绍：<a href="http://ihongqiqu.com/2018/01/10/weixin-app/" rel="external nofollow noopener noreferrer" target="_blank">http://ihongqiqu.com/2018/01/10/weixin-app/</a></p><h3 id="2-遇到的问题"><a href="#2-遇到的问题" class="headerlink" title="2. 遇到的问题"></a>2. 遇到的问题</h3><p>本小程序开发中，逻辑并不复杂。相对难处理一点就是中英文换行的问题。针对中英文换行的问题，我实现了一下换行逻辑，代码如下：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 文本转换为数组，数组里面分别是每行的文本内容，支持英文分行</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * ctx Context</span></span><br><span class="line"><span class="comment"> * txt 待换行的文本</span></span><br><span class="line"><span class="comment"> * width 需要显示文本的最大宽度</span></span><br><span class="line"><span class="comment"> * isEng 是否是英文</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">txt2arr: <span class="function"><span class="keyword">function</span> (<span class="params">ctx, txt, width, isEng</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> chr = txt.split(isEng ? <span class="string">" "</span> : <span class="string">""</span>);</span><br><span class="line">  <span class="keyword">var</span> temp = <span class="string">""</span>;</span><br><span class="line">  <span class="keyword">var</span> row = [];</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; chr.length; i++) &#123;</span><br><span class="line">    <span class="keyword">var</span> cur = chr[i];</span><br><span class="line">    <span class="keyword">var</span> tempWidth = ctx.measureText(temp).width;</span><br><span class="line">    <span class="keyword">var</span> curWidth = ctx.measureText(cur).width;</span><br><span class="line">    <span class="comment">// 需要考虑英文换行问题</span></span><br><span class="line">    <span class="keyword">if</span> (tempWidth + curWidth &lt; width) &#123;</span><br><span class="line">      temp += cur;</span><br><span class="line">      temp += (isEng ? <span class="string">" "</span> : <span class="string">""</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      row.push(temp);</span><br><span class="line">      temp = <span class="string">""</span>;</span><br><span class="line">      temp += cur;</span><br><span class="line">      temp += (isEng ? <span class="string">" "</span> : <span class="string">""</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  row.push(temp);</span><br><span class="line">  <span class="keyword">return</span> row;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>上面方法是把字符串处理为字符串数组，数组每个值代表一行，这里是换行核心逻辑，但不是全部逻辑，全部逻辑见核心代码调用。</p><h3 id="3-核心代码"><a href="#3-核心代码" class="headerlink" title="3. 核心代码"></a>3. 核心代码</h3><p>核心的 canvas 画图逻辑代码如下：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br></pre></td><td class="code"><pre><span class="line">drawShare: <span class="function"><span class="keyword">function</span> (<span class="params">imgPath, sRes</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> ctx = wx.createContext()</span><br><span class="line">  <span class="keyword">var</span> screenWidth = wx.getSystemInfoSync().windowWidth</span><br><span class="line">  <span class="keyword">var</span> screenHeight = wx.getSystemInfoSync().screenHeight</span><br><span class="line">  <span class="comment">// 小程序码宽度</span></span><br><span class="line">  <span class="keyword">var</span> qrWidth = <span class="number">80</span></span><br><span class="line">  <span class="comment">// 小程序码边距</span></span><br><span class="line">  <span class="keyword">var</span> qrMargin = screenHeight * <span class="number">0.02</span></span><br><span class="line">  <span class="comment">// 小程序码路径</span></span><br><span class="line">  <span class="keyword">var</span> qrPath = <span class="string">'../../img/ic_wx_mini.jpg'</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画背景图</span></span><br><span class="line">  <span class="comment">// ctx.drawImage(this.data.background, 0, 0, screenWidth, screenHeight - 30)</span></span><br><span class="line">  <span class="comment">// ctx.save()</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画白色背景</span></span><br><span class="line">  ctx.setFillStyle(<span class="string">"#FFFFFF"</span>)</span><br><span class="line">  ctx.fillRect(<span class="number">0</span>, <span class="number">0</span>, screenWidth, screenHeight)</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画右上角几何图形</span></span><br><span class="line">  ctx.setLineWidth(<span class="number">1</span>)</span><br><span class="line">  ctx.setStrokeStyle(<span class="string">"#079dd8"</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#079dd8"</span>)</span><br><span class="line">  ctx.beginPath()</span><br><span class="line">  ctx.moveTo(screenWidth * <span class="number">100</span> / <span class="number">640</span>, <span class="number">0</span>)</span><br><span class="line">  ctx.lineTo(screenWidth - screenWidth * <span class="number">100</span> / <span class="number">640</span>, screenHeight * <span class="number">140</span> / <span class="number">1000</span>)</span><br><span class="line">  ctx.lineTo(screenWidth, screenHeight * <span class="number">110</span> / <span class="number">1000</span>)</span><br><span class="line">  ctx.lineTo(screenWidth, <span class="number">0</span>)</span><br><span class="line">  ctx.fill()</span><br><span class="line">  ctx.stroke()</span><br><span class="line">  ctx.closePath()</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画日期</span></span><br><span class="line">  <span class="keyword">var</span> date = <span class="keyword">new</span> <span class="built_in">Date</span>()</span><br><span class="line">  ctx.setFontSize(<span class="number">40</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#FF8700"</span>)</span><br><span class="line">  ctx.fillText(<span class="string">''</span> + date.getDate(), <span class="number">15</span>, <span class="number">65</span>)</span><br><span class="line">  ctx.setFontSize(<span class="number">20</span>)</span><br><span class="line">  ctx.fillText(<span class="string">''</span> + (date.getMonth() + <span class="number">1</span>) + <span class="string">'.'</span> + date.getFullYear(), <span class="number">70</span>, <span class="number">65</span>)</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画每日一句-英文</span></span><br><span class="line">  ctx.setFontSize(<span class="number">22</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#BBBBBB"</span>)</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">"shareRes : "</span> + sRes);</span><br><span class="line">  <span class="keyword">var</span> arr = <span class="keyword">this</span>.txt2arr(ctx, sRes.content, screenWidth * <span class="number">0.9</span>, <span class="literal">true</span>)</span><br><span class="line">  <span class="comment">// console.log(arr)</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">    ctx.fillText(<span class="string">''</span> + arr[i], <span class="number">15</span>, screenHeight * <span class="number">145</span> / <span class="number">1000</span> + (i + <span class="number">1</span>) * <span class="number">24</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画每日一句-中文</span></span><br><span class="line">  ctx.setFontSize(<span class="number">14</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#7D7D7D"</span>)</span><br><span class="line">  <span class="comment">// ctx.fillText(sRes.note, 15, screenHeight * 375 / 1000)</span></span><br><span class="line">  <span class="keyword">var</span> arrZH = <span class="keyword">this</span>.txt2arr(ctx, sRes.note, screenWidth * <span class="number">0.9</span>, <span class="literal">false</span>)</span><br><span class="line">  <span class="comment">// console.log(arrCH)</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> k = <span class="number">0</span>; k &lt; arrZH.length; k++) &#123;</span><br><span class="line">    ctx.fillText(<span class="string">''</span> + arrZH[k], <span class="number">15</span>, screenHeight * <span class="number">345</span> / <span class="number">1000</span> + (k + <span class="number">1</span>) * <span class="number">16</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画配图</span></span><br><span class="line">  <span class="keyword">var</span> picY = screenHeight * <span class="number">0.4</span></span><br><span class="line">  <span class="keyword">var</span> picHeight = screenWidth * <span class="number">580</span> / <span class="number">938</span></span><br><span class="line">  ctx.drawImage(<span class="keyword">this</span>.data.background, <span class="number">0</span>, picY, screenWidth, picHeight)</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画渐变</span></span><br><span class="line">  <span class="keyword">var</span> grd = ctx.createLinearGradient(screenWidth / <span class="number">2</span>, picY - <span class="number">2</span>, screenWidth / <span class="number">2</span>, picY * <span class="number">1.3</span>);</span><br><span class="line">  grd.addColorStop(<span class="number">0</span>, <span class="string">'rgba(255, 255, 255, 1)'</span>)</span><br><span class="line">  grd.addColorStop(<span class="number">1</span>, <span class="string">'rgba(255, 255, 255, 0)'</span>)</span><br><span class="line">  ctx.setFillStyle(grd)</span><br><span class="line">  ctx.fillRect(<span class="number">0</span>, picY - <span class="number">2</span>, screenWidth, picHeight / <span class="number">3</span>)</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画底部梯形</span></span><br><span class="line">  <span class="keyword">var</span> blueHeight = picY + picHeight;</span><br><span class="line">  ctx.setLineWidth(<span class="number">5</span>)</span><br><span class="line">  ctx.setStrokeStyle(<span class="string">"#079dd8"</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#079dd8"</span>)</span><br><span class="line">  ctx.beginPath()</span><br><span class="line">  ctx.moveTo(<span class="number">0</span>, blueHeight - screenWidth * <span class="number">70</span> / <span class="number">640</span>)</span><br><span class="line">  ctx.lineTo(screenWidth, blueHeight)</span><br><span class="line">  ctx.lineTo(screenWidth, screenHeight)</span><br><span class="line">  ctx.lineTo(<span class="number">0</span>, screenHeight)</span><br><span class="line">  ctx.lineTo(<span class="number">0</span>, blueHeight - screenWidth * <span class="number">70</span> / <span class="number">640</span>)</span><br><span class="line">  ctx.fill()</span><br><span class="line">  ctx.stroke()</span><br><span class="line">  ctx.closePath()</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画小编的话</span></span><br><span class="line">  ctx.setFontSize(<span class="number">12</span>)</span><br><span class="line">  ctx.setFillStyle(<span class="string">"#FFFFFF"</span>)</span><br><span class="line">  <span class="keyword">var</span> arr2 = <span class="keyword">this</span>.txt2arr(ctx, sRes.translation, screenWidth * <span class="number">0.6</span>)</span><br><span class="line">  <span class="built_in">console</span>.log(arr)</span><br><span class="line">  <span class="keyword">var</span> startHeight = blueHeight * <span class="number">1.04</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> j = <span class="number">0</span>; j &lt; arr2.length; j++) &#123;</span><br><span class="line">    ctx.fillText(<span class="string">''</span> + arr2[j], <span class="number">15</span>, startHeight + j * <span class="number">18</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 画小程序码</span></span><br><span class="line">  ctx.setLineWidth(<span class="number">1</span>)</span><br><span class="line">  ctx.beginPath()</span><br><span class="line">  ctx.arc(screenWidth - qrWidth / <span class="number">2</span> - qrMargin, screenHeight - qrWidth / <span class="number">2</span> - qrMargin, qrWidth / <span class="number">2</span>, <span class="number">0</span>, <span class="number">2</span> * <span class="built_in">Math</span>.PI)</span><br><span class="line">  ctx.setStrokeStyle(<span class="string">"#ffff00"</span>)</span><br><span class="line">  ctx.stroke()</span><br><span class="line">  ctx.clip()</span><br><span class="line">  ctx.drawImage(qrPath, screenWidth - qrWidth - qrMargin, screenHeight - qrWidth - qrMargin, qrWidth, qrWidth)</span><br><span class="line">  ctx.save()</span><br><span class="line"></span><br><span class="line">  wx.drawCanvas(&#123;</span><br><span class="line">    canvasId: <span class="string">'canvas'</span>,</span><br><span class="line">    actions: ctx.getActions()</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>有任何问题欢迎留言反馈。</p><p><br>本文地址 <a href="http://94275.cn/2018/11/19/wxminiapp-canvas/">http://94275.cn/2018/11/19/wxminiapp-canvas/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;微信小程序目前仅支持分享给好友，暂不支持直接分享到朋友圈。针对分享到朋友圈这个问题，通常的做法是生成一张海报图片然后把图片分享到朋友圈。朋友圈到我们的小程序，通过长按图片识别图中小程序码实现。&lt;img src=&quot;https://img.shields.io/badge/wx-canvas-green.svg&quot; alt=&quot;WX Canvas&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="微信小程序" scheme="http://94275.cn/categories/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>Webpack4 入门</title>
    <link href="http://94275.cn/2018/11/13/webpack4-intro/"/>
    <id>http://94275.cn/2018/11/13/webpack4-intro/</id>
    <published>2018-11-13T06:22:18.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><h3 id="1-基本介绍"><a href="#1-基本介绍" class="headerlink" title="1. 基本介绍"></a>1. 基本介绍</h3><blockquote><p>本质上，webpack 是一个现代 JavaScript 应用程序的静态模块打包器(static module bundler)。</p></blockquote><p>Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔，等到实际需要的时候再异步加载。通过 loader 的转换，任何形式的资源都可以视作模块，比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。</p><a id="more"></a><h3 id="2-安装"><a href="#2-安装" class="headerlink" title="2. 安装"></a>2. 安装</h3><p>Webpack4 将命令行相关抽离到 webpack-cli 中，所以要使用 webpack 也要安装 webpack-cli。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install webpack webpack-cli webpack-dev-server -g</span><br></pre></td></tr></table></figure><h3 id="3-核心概念"><a href="#3-核心概念" class="headerlink" title="3. 核心概念"></a>3. 核心概念</h3><p>webpack 最核心的概念主要有以下四个：</p><ol><li>entry （入口）</li><li>output（输出）</li><li>loader（加载器）</li><li>plugins（插件）</li></ol><h4 id="3-1-entry（入口）"><a href="#3-1-entry（入口）" class="headerlink" title="3.1 entry（入口）"></a>3.1 entry（入口）</h4><p>entry 指定 weipack 应该使用哪个模块来作为构建内部依赖的开始。多页面应用也在这里配置。</p><p>webpack.config.js 的 entry 配置示例如下：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">var path = require('path');</span><br><span class="line">const HtmlWebpackPlugin = require("html-webpack-plugin");</span><br><span class="line">module.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        index: './src/js/index.js',</span><br><span class="line">        hello: './src/js/hello.js'</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h4 id="3-2-output-输出"><a href="#3-2-output-输出" class="headerlink" title="3.2 output (输出)"></a>3.2 output (输出)</h4><p>output 选项可以控制 webpack 如何向硬盘写入编译文件。注意，即使可以存在多个入口起点，但只指定一个输出配置。</p><p>webpack.config.js 的 output 配置示例如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">var path = require(&apos;path&apos;);</span><br><span class="line">const HtmlWebpackPlugin = require(&quot;html-webpack-plugin&quot;);</span><br><span class="line">module.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        index: &apos;./src/js/index.js&apos;,</span><br><span class="line">        hello: &apos;./src/js/hello.js&apos;</span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, &apos;./dist&apos;),</span><br><span class="line">        filename: &apos;js/[name]-[chunkhash].js&apos;</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h4 id="3-3-loader（加载器）"><a href="#3-3-loader（加载器）" class="headerlink" title="3.3 loader（加载器）"></a>3.3 loader（加载器）</h4><p>loader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此，loader 类似于其他构建工具中“任务(task)”，并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言（如 TypeScript）转换为 JavaScript，或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件！</p><p>常用的 loader 有 style、css、url、html等。安装插件命令如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev css-loader style-loader</span><br></pre></td></tr></table></figure><p>webpack.config.js 的 loader 配置示例如下：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">module.exports = &#123;</span><br><span class="line">    module: &#123;</span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: /\.js?$/,</span><br><span class="line">                exclude: /node_modules/,</span><br><span class="line">                loader: 'babel-loader',</span><br><span class="line">                query: &#123;</span><br><span class="line">                    presets: ['es2015']</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: /\.css$/,</span><br><span class="line">                loader: ['style-loader', 'css-loader']</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: /\.html$/,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: "html-loader",</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            attrs: ["img:src"]</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: /\.(png|jpg|jpeg|gif)$/,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: "url-loader",</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            name: "[name]-[hash:5].min.[ext]",</span><br><span class="line">                            limit: 10000, // size &lt;= 20KB</span><br><span class="line">                            publicPath: "static/",</span><br><span class="line">                            outputPath: "static/"</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h4 id="3-4-plugins（插件）"><a href="#3-4-plugins（插件）" class="headerlink" title="3.4 plugins（插件）"></a>3.4 plugins（插件）</h4><p>插件是 webpack 的支柱功能。webpack 自身也是构建于，你在 webpack 配置中用到的相同的插件系统之上！插件目的在于解决 loader 无法实现的其他事。</p><p>webpack.config.js 的 plugins 的配置示例如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">const HtmlWebpackPlugin = require(&quot;html-webpack-plugin&quot;);</span><br><span class="line">module.exports = &#123;</span><br><span class="line"></span><br><span class="line">    plugins: [</span><br><span class="line">        new HtmlWebpackPlugin(&#123;</span><br><span class="line">            // filename: &quot;index.html&quot;,</span><br><span class="line">            template: &quot;./src/index.html&quot;,</span><br><span class="line">            inject: &quot;head&quot;,</span><br><span class="line">            // chunks: [&quot;src&quot;], // entry中的app入口才会被打包</span><br><span class="line">            minify: &#123;</span><br><span class="line">                // 压缩选项</span><br><span class="line">                collapseWhitespace: true</span><br><span class="line">            &#125;,</span><br><span class="line">            title: &apos;webpack test title&apos;</span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3 id="4-总结"><a href="#4-总结" class="headerlink" title="4. 总结"></a>4. 总结</h3><p>webpack 主要解决了组件封装，规范测试打包上线流程，把很多需要手动处理和配置的工作工具化，给我们提供极大便利。wepack 并不复杂，熟悉核心的概念就能打造出符合我们要求的脚本。</p><h3 id="5-参考"><a href="#5-参考" class="headerlink" title="5. 参考"></a>5. 参考</h3><p>webpack 官方文档地址：<a href="https://webpack.js.org/" rel="external nofollow noopener noreferrer" target="_blank">https://webpack.js.org/</a></p><p>webpack 中文文档地址：<a href="https://webpack.css88.com/" rel="external nofollow noopener noreferrer" target="_blank">https://webpack.css88.com/</a></p><h3 id="6-代码"><a href="#6-代码" class="headerlink" title="6. 代码"></a>6. 代码</h3><p>示例代码地址：<a href="https://github.com/jingle1267/webpack-hello.git" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/webpack-hello.git</a></p><p><br>本文地址 <a href="http://94275.cn/2018/11/13/webpack4-intro/">http://94275.cn/2018/11/13/webpack4-intro/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;h3 id=&quot;1-基本介绍&quot;&gt;&lt;a href=&quot;#1-基本介绍&quot; class=&quot;headerlink&quot; title=&quot;1. 基本介绍&quot;&gt;&lt;/a&gt;1. 基本介绍&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;本质上，webpack 是一个现代 JavaScript 应用程序的静态模块打包器(static module bundler)。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔，等到实际需要的时候再异步加载。通过 loader 的转换，任何形式的资源都可以视作模块，比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。&lt;/p&gt;
    
    </summary>
    
      <category term="webpack" scheme="http://94275.cn/categories/webpack/"/>
    
    
      <category term="webpack" scheme="http://94275.cn/tags/webpack/"/>
    
  </entry>
  
  <entry>
    <title>微信小程序从入门到放弃</title>
    <link href="http://94275.cn/2018/09/20/wxmini-in-out/"/>
    <id>http://94275.cn/2018/09/20/wxmini-in-out/</id>
    <published>2018-09-20T03:22:56.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><h3 id="本文主要内容"><a href="#本文主要内容" class="headerlink" title="本文主要内容"></a>本文主要内容</h3><ol><li>小程序组件</li><li>小程序接口</li><li>小程序 vs H5</li><li>小程序新特性</li><li>放弃</li></ol><a id="more"></a><h3 id="1-小程序组件"><a href="#1-小程序组件" class="headerlink" title="1. 小程序组件"></a>1. 小程序组件</h3><h4 id="1-1-小程序组件脑图"><a href="#1-1-小程序组件脑图" class="headerlink" title="1.1 小程序组件脑图"></a>1.1 小程序组件脑图</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wxmini_component.jpg" alt="小程序组件"></p><h4 id="1-2-小程序组件二维码"><a href="#1-2-小程序组件二维码" class="headerlink" title="1.2 小程序组件二维码"></a>1.2 小程序组件二维码</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/xcxzj.png" alt="小程序组件二维码"></p><h3 id="2-小程序接口"><a href="#2-小程序接口" class="headerlink" title="2. 小程序接口"></a>2. 小程序接口</h3><h4 id="2-1-小程序接口脑图"><a href="#2-1-小程序接口脑图" class="headerlink" title="2.1 小程序接口脑图"></a>2.1 小程序接口脑图</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wxmini_api.jpg" alt="小程序接口"></p><h4 id="2-2-小程序接口二维码"><a href="#2-2-小程序接口二维码" class="headerlink" title="2.2 小程序接口二维码"></a>2.2 小程序接口二维码</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/xcxjk.png" alt="小程序接口二维码"></p><h4 id="2-3-登录态打通"><a href="#2-3-登录态打通" class="headerlink" title="2.3 登录态打通"></a>2.3 登录态打通</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wx_mini2h5.jpeg" alt="小程序接口二维码"></p><h3 id="3-小程序-vs-H5"><a href="#3-小程序-vs-H5" class="headerlink" title="3. 小程序 vs H5"></a>3. 小程序 vs H5</h3><h4 id="3-1-标签对比"><a href="#3-1-标签对比" class="headerlink" title="3.1 标签对比"></a>3.1 标签对比</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wx_h5_sign.png" alt="小程序vsH5"></p><h4 id="3-2-选图上传"><a href="#3-2-选图上传" class="headerlink" title="3.2 选图上传"></a>3.2 选图上传</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wx_h5_upload.png" alt="小程序vsH5"></p><h4 id="3-3-开发框架对比"><a href="#3-3-开发框架对比" class="headerlink" title="3.3 开发框架对比"></a>3.3 开发框架对比</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wx_compare.png" alt="小程序vsH5"></p><h3 id="4-小程序新特性"><a href="#4-小程序新特性" class="headerlink" title="4. 小程序新特性"></a>4. 小程序新特性</h3><ol><li>支持自定义标题栏</li><li>分包加载</li><li>云开发</li></ol><h3 id="5-放弃"><a href="#5-放弃" class="headerlink" title="5. 放弃"></a>5. 放弃</h3><h4 id="5-1-遇到过的问题"><a href="#5-1-遇到过的问题" class="headerlink" title="5.1 遇到过的问题"></a>5.1 遇到过的问题</h4><p><img src="http://ppt.94275.cn/assets/images/weixin/wx_question.png" alt="wx_question"></p><h4 id="5-2-微信的限制"><a href="#5-2-微信的限制" class="headerlink" title="5.2 微信的限制"></a>5.2 微信的限制</h4><ol><li>服务器域名和业务域名限制</li><li>页面层级最大10</li><li>服务通知 formId payId</li><li>只可微信支付</li><li>打开APP</li><li>…</li></ol><h4 id="5-3-大坑预警web-view"><a href="#5-3-大坑预警web-view" class="headerlink" title="5.3 大坑预警web-view"></a>5.3 大坑预警web-view</h4><h5 id="5-3-1-优点"><a href="#5-3-1-优点" class="headerlink" title="5.3.1 优点"></a>5.3.1 优点</h5><p>不需重复开发，H5拿来就能用</p><h5 id="5-3-2"><a href="#5-3-2" class="headerlink" title="5.3.2"></a>5.3.2</h5><ol><li>用户体验没有原生好</li><li>限制较多，业务域名校验和数量限制</li><li>原生和小程序交互能力薄弱</li><li>web-view层级高会覆盖其他组件</li></ol><h4 id="5-4-限制加强项目"><a href="#5-4-限制加强项目" class="headerlink" title="5.4 限制加强项目"></a>5.4 限制加强项目</h4><ol><li>限制分享</li><li>getUserInfo</li><li>打开设置</li></ol><h3 id="手机上看"><a href="#手机上看" class="headerlink" title="手机上看"></a>手机上看</h3><p><img src="http://ppt.94275.cn/assets/images/weixin/qr_ppt.png" alt="小程序组件二维码"></p><h3 id="iOS手机专享-慎扫"><a href="#iOS手机专享-慎扫" class="headerlink" title="iOS手机专享-慎扫"></a>iOS手机专享-慎扫</h3><p><img src="http://ppt.94275.cn/assets/images/weixin/ios_shutdown.png" alt="小程序组件二维码"></p><p>PPT链接地址：<a href="http://ppt.94275.cn/wxmini-in-out/index.html#/" rel="external nofollow noopener noreferrer" target="_blank">http://ppt.94275.cn/wxmini-in-out/index.html#/</a></p><p><br>本文地址 <a href="http://94275.cn/2018/09/20/wxmini-in-out/">http://94275.cn/2018/09/20/wxmini-in-out/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;h3 id=&quot;本文主要内容&quot;&gt;&lt;a href=&quot;#本文主要内容&quot; class=&quot;headerlink&quot; title=&quot;本文主要内容&quot;&gt;&lt;/a&gt;本文主要内容&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;小程序组件&lt;/li&gt;&lt;li&gt;小程序接口&lt;/li&gt;&lt;li&gt;小程序 vs H5&lt;/li&gt;&lt;li&gt;小程序新特性&lt;/li&gt;&lt;li&gt;放弃&lt;/li&gt;&lt;/ol&gt;
    
    </summary>
    
      <category term="微信小程序" scheme="http://94275.cn/categories/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
  </entry>
  
  <entry>
    <title>微信小程序API</title>
    <link href="http://94275.cn/2018/08/27/weixin-mini-app-api/"/>
    <id>http://94275.cn/2018/08/27/weixin-mini-app-api/</id>
    <published>2018-08-27T06:20:04.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>话不说，直接看图：</p><a id="more"></a><p><img src="/imgs/post/wx_api_mindmap.png" alt="/imgs/post/wx_api_mindmap.png"></p><p>图片来自<a href="https://www.processon.com/i/5467870be4b054d6db9d9ad8" rel="external nofollow noopener noreferrer" target="_blank">ProcessOn</a>，脑图链接：<a href="https://www.processon.com/view/5b4eaf41e4b0f8477d878109" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/view/5b4eaf41e4b0f8477d878109</a></p><p><br>本文地址 <a href="http://94275.cn/2018/08/27/weixin-mini-app-api/">http://94275.cn/2018/08/27/weixin-mini-app-api/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;话不说，直接看图：&lt;/p&gt;
    
    </summary>
    
      <category term="微信小程序" scheme="http://94275.cn/categories/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序API" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8FAPI/"/>
    
  </entry>
  
  <entry>
    <title>微信小程序组件介绍</title>
    <link href="http://94275.cn/2018/08/21/wexin-mini-component/"/>
    <id>http://94275.cn/2018/08/21/wexin-mini-component/</id>
    <published>2018-08-21T06:20:29.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>话不多说，直接上脑图</p><a id="more"></a><p><img src="/imgs/post/wx_component_mindmap.png" alt="微信小程序组件介绍脑图"></p><p>图片来自<a href="https://www.processon.com/i/5467870be4b054d6db9d9ad8" rel="external nofollow noopener noreferrer" target="_blank">ProcessOn</a>，脑图链接：<a href="https://www.processon.com/view/5b4eaf41e4b0f8477d878109" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/view/5b4eaf41e4b0f8477d878109</a></p><p><br>本文地址 <a href="http://94275.cn/2018/08/21/wexin-mini-component/">http://94275.cn/2018/08/21/wexin-mini-component/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;话不多说，直接上脑图&lt;/p&gt;
    
    </summary>
    
      <category term="微信小程序" scheme="http://94275.cn/categories/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序组件" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%BB%84%E4%BB%B6/"/>
    
  </entry>
  
  <entry>
    <title>Git工作流</title>
    <link href="http://94275.cn/2018/04/17/git-flow/"/>
    <id>http://94275.cn/2018/04/17/git-flow/</id>
    <published>2018-04-17T01:23:44.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><a id="more"></a><p><img src="http://on-img.com/chart_image/5ad46af0e4b0518eacb413fd.png" alt="Git Flow"></p><p><a href="https://www.processon.com/diagraming/5ad46af0e4b0518eacb413f8" rel="external nofollow noopener noreferrer" target="_blank">https://www.processon.com/diagraming/5ad46af0e4b0518eacb413f8</a></p><p><br>本文地址 <a href="http://94275.cn/2018/04/17/git-flow/">http://94275.cn/2018/04/17/git-flow/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;
    
    </summary>
    
      <category term="Git" scheme="http://94275.cn/categories/Git/"/>
    
    
      <category term="Git Flow" scheme="http://94275.cn/tags/Git-Flow/"/>
    
  </entry>
  
  <entry>
    <title>三国主要人物关系</title>
    <link href="http://94275.cn/2018/04/13/caocao/"/>
    <id>http://94275.cn/2018/04/13/caocao/</id>
    <published>2018-04-13T06:56:28.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><a id="more"></a><p><img src="/imgs/post/caocao_mindmap.jpg" alt="三国主要人物关系"></p><p><a href="http://on-img.com/chart_image/5a97cbcbe4b09a29d512e3dd.png" rel="external nofollow noopener noreferrer" target="_blank">http://on-img.com/chart_image/5a97cbcbe4b09a29d512e3dd.png</a></p><p><br>本文地址 <a href="http://94275.cn/2018/04/13/caocao/">http://94275.cn/2018/04/13/caocao/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;
    
    </summary>
    
      <category term="历史人物" scheme="http://94275.cn/categories/%E5%8E%86%E5%8F%B2%E4%BA%BA%E7%89%A9/"/>
    
    
  </entry>
  
  <entry>
    <title>微信小程序之页面模板</title>
    <link href="http://94275.cn/2018/04/09/wxminiapp-template/"/>
    <id>http://94275.cn/2018/04/09/wxminiapp-template/</id>
    <published>2018-04-09T03:25:48.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>微信小程序提供了页面模板支持，很大程度解决了<em>页面布局复用</em>的问题。</p><a id="more"></a><p>官方说明</p><blockquote><p>WXML提供模板（template），可以在模板中定义代码片段，然后在不同的地方调用。</p></blockquote><p>小程序的模板并不难，下面整理了一些基本流程，方便快速上手小程序页面模板。</p><h3 id="1-定义模板布局"><a href="#1-定义模板布局" class="headerlink" title="1. 定义模板布局"></a>1. 定义模板布局</h3><p>建议新建目录专门放置模板。本文在pages目录下创建了template目录。</p><p>在template目录下创建模板布局文件msg.wxml：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">!--</span><br><span class="line">  index: int</span><br><span class="line">  msg: string</span><br><span class="line">  time: string</span><br><span class="line">--&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">template</span> <span class="attr">name</span>=<span class="string">"msgItem"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">view</span> <span class="attr">class</span>=<span class="string">'msgBg'</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">text</span>&gt;</span> &#123;&#123;index&#125;&#125;: &#123;&#123;msg&#125;&#125; <span class="tag">&lt;/<span class="name">text</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">text</span>&gt;</span> Time: &#123;&#123;time&#125;&#125; <span class="tag">&lt;/<span class="name">text</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">view</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br></pre></td></tr></table></figure><p>上面代码中template表现的name是模板的id；</p><h3 id="2-定义模板样式"><a href="#2-定义模板样式" class="headerlink" title="2. 定义模板样式"></a>2. 定义模板样式</h3><p>创建模板样式，建议和模板布局放到相同目录；</p><p>在template目录下的模板样式文件msg.wxss：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.msgBg</span> &#123;</span><br><span class="line">  <span class="attribute">background</span>: <span class="number">#099</span>;</span><br><span class="line">  <span class="attribute">padding</span>: <span class="number">0.5rem</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-引用模板"><a href="#3-引用模板" class="headerlink" title="3. 引用模板"></a>3. 引用模板</h3><p>在需要应用模板的地方添加引用：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--引入模板--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">import</span> <span class="attr">src</span>=<span class="string">"../template/msg.wxml"</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>在需要使用模板的地方添加引用代码：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 使用模板 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span> <span class="attr">is</span>=<span class="string">"msgItem"</span> <span class="attr">data</span>=<span class="string">"&#123;&#123;...itemOne&#125;&#125;"</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>完成的业务引用代码如下（index.wxml）：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--引入模板--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">import</span> <span class="attr">src</span>=<span class="string">"../template/msg.wxml"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">view</span> <span class="attr">class</span>=<span class="string">"container"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">&lt;!-- 使用模板 --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">template</span> <span class="attr">is</span>=<span class="string">"msgItem"</span> <span class="attr">data</span>=<span class="string">"&#123;&#123;...itemOne&#125;&#125;"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">&lt;!-- 使用模板for --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">block</span> <span class="attr">wx:for</span>=<span class="string">"&#123;&#123;items&#125;&#125;"</span> <span class="attr">wx:for-item</span>=<span class="string">"item"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">template</span> <span class="attr">is</span>=<span class="string">"msgItem"</span> <span class="attr">data</span>=<span class="string">"&#123;&#123;...item&#125;&#125;"</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">block</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">view</span>&gt;</span></span><br></pre></td></tr></table></figure><p>is是模板id，data负责传值；data传值使用ES6展开运算符”…”，那么就不需要在模板里面添加item.XXX了。</p><h3 id="4-引用样式"><a href="#4-引用样式" class="headerlink" title="4. 引用样式"></a>4. 引用样式</h3><p>模板样式也需要添加引用，在引用方的样式代码中添加引用代码如下：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**引入模板的样式**/</span></span><br><span class="line">@<span class="keyword">import</span> <span class="string">"../template/msg.wxss"</span>;</span><br></pre></td></tr></table></figure><p>完成的样式引用代码如下（index.wxss）：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**引入模板的样式**/</span></span><br><span class="line">@<span class="keyword">import</span> <span class="string">"../template/msg.wxss"</span>;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.container</span> &#123;</span><br><span class="line">  <span class="attribute">background</span>: <span class="number">#ff0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="5-赋值初始化"><a href="#5-赋值初始化" class="headerlink" title="5. 赋值初始化"></a>5. 赋值初始化</h3><p>通过以上四个步骤，模板布局和样式都有了，剩下的就是如何复制和展示数据了。 代码如下（index.js）：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//index.js</span></span><br><span class="line"><span class="comment">//获取应用实例</span></span><br><span class="line"><span class="keyword">const</span> app = getApp()</span><br><span class="line"></span><br><span class="line">Page(&#123;</span><br><span class="line">  data: &#123;</span><br><span class="line">    motto: <span class="string">'Hello World'</span>,</span><br><span class="line">    itemOne: &#123;</span><br><span class="line">      index: <span class="number">999</span>,</span><br><span class="line">      msg: <span class="string">'this is a template'</span>,</span><br><span class="line">      time: <span class="string">'2018-01-08'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    items: [&#123;</span><br><span class="line">      index: <span class="number">0</span>,</span><br><span class="line">      msg: <span class="string">'template1'</span>,</span><br><span class="line">      time: <span class="string">'2016-09-15'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      index: <span class="number">1</span>,</span><br><span class="line">      msg: <span class="string">'emplate2'</span>,</span><br><span class="line">      time: <span class="string">'2016-09-16'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      index: <span class="number">2</span>,</span><br><span class="line">      msg: <span class="string">'emplate3'</span>,</span><br><span class="line">      time: <span class="string">'2016-09-17'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      index: <span class="number">3</span>,</span><br><span class="line">      msg: <span class="string">'emplate4'</span>,</span><br><span class="line">      time: <span class="string">'2016-09-18'</span></span><br><span class="line">    &#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>官方介绍地址：<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html" rel="external nofollow noopener noreferrer" target="_blank">https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html</a></p><p><br>本文地址 <a href="http://94275.cn/2018/04/09/wxminiapp-template/">http://94275.cn/2018/04/09/wxminiapp-template/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;微信小程序提供了页面模板支持，很大程度解决了&lt;em&gt;页面布局复用&lt;/em&gt;的问题。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="http://94275.cn/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>微信小程序之坑</title>
    <link href="http://94275.cn/2018/04/04/wx-mini-app-bug/"/>
    <id>http://94275.cn/2018/04/04/wx-mini-app-bug/</id>
    <published>2018-04-04T07:00:27.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>微信小程序因其“小”和“轻”，以及微信爸爸的用户量，受到了大家的青睐。下面总结了，我在开发微信小程序的过程中，踩过的坑。希望能够帮助更多的人。</p><a id="more"></a><h3 id="1-服务器域名"><a href="#1-服务器域名" class="headerlink" title="1. 服务器域名"></a>1. 服务器域名</h3><p>微信小程序中<strong>所有</strong>网络通信域名，首先都需要在工信部备案，其次都需要在小程序后台添加合法域名。域名主要有四类：request域名、socket域名、upload域名、download域名；其次，在修改次数上也有限制。下面详细说。</p><h3 id="2-业务域名"><a href="#2-业务域名" class="headerlink" title="2. 业务域名"></a>2. 业务域名</h3><p>这个问题主要针对使用web-view组件的情况。web-view 组件是一个可以用来承载网页的容器，会自动铺满整个小程序页面。<strong>个人类型与海外类型的小程序暂不支持使用。</strong></p><p>web-view中需要加载的所有域名都需要在微信小程序后台配置。</p><p>正确的打开方式是：</p><ol><li>在微信开发者后台-设置-开发设置中添加/修改业务域名，<strong>下载校验文件</strong>。</li><li>在需要访问的业务域名根目录添加第一步下载的校验文件。</li><li>在第一步打开的窗口添加业务域名（必须有第2步，否则添加不成功）。</li></ol><p>如果我们需要在web-view中显示的是一些单页面，这没有什么问题。但是，如果使用了复合页面，涉及到很多页面跳转，那就麻烦了。所有涉及跳转的域名都需要业务域名校验，对是<em>所有的业务域名</em>。如果跳转到三方域名，或者很多外链，添加业务域名校验文件就是很大的难题。</p><p>这可能也是微信故意这样设计，微信不推荐使用web-view做很重的业务，这个符合微信小程序的小而轻原则。</p><h3 id="3-次数限制"><a href="#3-次数限制" class="headerlink" title="3. 次数限制"></a>3. 次数限制</h3><table><thead><tr><th>功能</th><th>功能介绍</th><th>次数</th></tr></thead><tbody><tr><td>小程序头像</td><td>小程序的logo</td><td>5次/月</td></tr><tr><td>介绍</td><td>小程序的介绍信息</td><td>5次/月</td></tr><tr><td>服务类目</td><td>小程序的分类(类目)</td><td>3次/月</td></tr><tr><td>服务器域名</td><td>小程序访问的接口域名</td><td>5次/月</td></tr><tr><td>业务域名</td><td>H5页面的域名</td><td>50次/年</td></tr></tbody></table><h3 id="4-数量限制"><a href="#4-数量限制" class="headerlink" title="4. 数量限制"></a>4. 数量限制</h3><table><thead><tr><th>限制</th><th>介绍</th><th>数量</th></tr></thead><tbody><tr><td>服务器域名</td><td>主要包括：request、socket、upload、download</td><td>20个 * 4</td></tr><tr><td>小程序业务域名</td><td>小程序可以配置的H5页面的域名</td><td>20个</td></tr><tr><td>单业务域名</td><td>每个域名最多可以添加小程序校验文件的数量</td><td>20个</td></tr></tbody></table><p><br>本文地址 <a href="http://94275.cn/2018/04/04/wx-mini-app-bug/">http://94275.cn/2018/04/04/wx-mini-app-bug/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;微信小程序因其“小”和“轻”，以及微信爸爸的用户量，受到了大家的青睐。下面总结了，我在开发微信小程序的过程中，踩过的坑。希望能够帮助更多的人。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="http://94275.cn/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>微信小程序介绍</title>
    <link href="http://94275.cn/2018/01/10/weixin-app/"/>
    <id>http://94275.cn/2018/01/10/weixin-app/</id>
    <published>2018-01-10T08:34:24.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>微信小程序是一种全新的连接用户与服务的方式，它可以在微信内被便捷地获取和传播，同时具有出色的使用体验。</p><a id="more"></a><h3 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h3><h4 id="申请账号"><a href="#申请账号" class="headerlink" title="申请账号"></a>申请账号</h4><p>访问 <a href="https://mp.weixin.qq.com/wxopen/waregister?action=step1" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com/wxopen/waregister?action=step1</a> 根据提示完成注册账号。注册完成后，登陆 <a href="https://mp.weixin.qq.com" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com</a> ，在设置-开发设置中可以找到小程序 AppID。</p><h4 id="安装开发工具"><a href="#安装开发工具" class="headerlink" title="安装开发工具"></a>安装开发工具</h4><p>微信小程序开发工具下载地址：<a href="https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=201818" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=201818</a><br>开发工具详细介绍见：<a href="https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html?t=201818" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html?t=201818</a></p><h4 id="Hello-World"><a href="#Hello-World" class="headerlink" title="Hello World"></a>Hello World</h4><p>打开微信开发者工具，登录后点击右下角”+”按钮，进入如下界面：</p><p><img src="/imgs/post/wx_app_init.png" alt="Project Init"></p><p>选择项目目录，填写刚刚申请的 AppID 和x项目名称。并选中”建立普通快速启动模板”。点击创建，Hello World就创建出来了。</p><h3 id="项目结构介绍"><a href="#项目结构介绍" class="headerlink" title="项目结构介绍"></a>项目结构介绍</h3><p>项目目录结构如图：</p><p><img src="/imgs/post/wx_app_pj_info.png" alt="Project Info"></p><h4 id="APP-JSON"><a href="#APP-JSON" class="headerlink" title="APP.JSON"></a>APP.JSON</h4><p>app.json 是对当前小程序的全局配置，包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。</p><p>例子：<br></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  "pages":[</span><br><span class="line">    "pages/index/index",</span><br><span class="line">    "pages/logs/logs"</span><br><span class="line">  ],</span><br><span class="line">  "window":&#123;</span><br><span class="line">    "backgroundTextStyle":"light",</span><br><span class="line">    "navigationBarBackgroundColor": "#fff",</span><br><span class="line">    "navigationBarTitleText": "WeChat",</span><br><span class="line">    "navigationBarTextStyle":"black"</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>pages 和 window 介绍：</p><ol><li>pages字段：用于描述当前小程序所有页面路径，这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。</li><li>window字段：小程序所有页面的顶部背景颜色，文字颜色定义在这里的。</li></ol><h4 id="WXML"><a href="#WXML" class="headerlink" title="WXML"></a>WXML</h4><p>类似网页编程的HTML，代码如下：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--index.wxml--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">view</span> <span class="attr">class</span>=<span class="string">"container"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">view</span> <span class="attr">class</span>=<span class="string">"userinfo"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">wx:if</span>=<span class="string">"&#123;&#123;!hasUserInfo &amp;&amp; canIUse&#125;&#125;"</span> <span class="attr">open-type</span>=<span class="string">"getUserInfo"</span> <span class="attr">bindgetuserinfo</span>=<span class="string">"getUserInfo"</span>&gt;</span> 获取头像昵称 <span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">block</span> <span class="attr">wx:else</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">image</span> <span class="attr">bindtap</span>=<span class="string">"bindViewTap"</span> <span class="attr">class</span>=<span class="string">"userinfo-avatar"</span> <span class="attr">src</span>=<span class="string">"&#123;&#123;userInfo.avatarUrl&#125;&#125;"</span> <span class="attr">background-size</span>=<span class="string">"cover"</span>&gt;</span><span class="tag">&lt;/<span class="name">image</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">text</span> <span class="attr">class</span>=<span class="string">"userinfo-nickname"</span>&gt;</span>&#123;&#123;userInfo.nickName&#125;&#125;<span class="tag">&lt;/<span class="name">text</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">block</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">view</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">view</span> <span class="attr">class</span>=<span class="string">"usermotto"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">text</span> <span class="attr">class</span>=<span class="string">"user-motto"</span>&gt;</span>&#123;&#123;motto&#125;&#125;<span class="tag">&lt;/<span class="name">text</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">view</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">view</span>&gt;</span></span><br></pre></td></tr></table></figure><p>从上面代码可以看出，代码风格很像HTML，同时也有自己的语法如wx:if和wx:else。更多语法请参考 <a href="https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxml/" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxml/</a> 。</p><h4 id="WXSS"><a href="#WXSS" class="headerlink" title="WXSS"></a>WXSS</h4><p>WXSS 具有 CSS 大部分的特性，小程序在 WXSS 也做了一些扩充和修改。示例代码如下：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**index.wxss**/</span></span><br><span class="line"><span class="selector-class">.userinfo</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: flex;</span><br><span class="line">  <span class="attribute">flex-direction</span>: column;</span><br><span class="line">  <span class="attribute">align-items</span>: center;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.userinfo-avatar</span> &#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">128</span>rpx;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">128</span>rpx;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">20</span>rpx;</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">50%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.userinfo-nickname</span> &#123;</span><br><span class="line">  <span class="attribute">color</span>: <span class="number">#aaa</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.usermotto</span> &#123;</span><br><span class="line">  <span class="attribute">margin-top</span>: <span class="number">200px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>更多详细请参考 <a href="https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxss.html" rel="external nofollow noopener noreferrer" target="_blank">https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxss.html</a></p><h4 id="JavaScript"><a href="#JavaScript" class="headerlink" title="JavaScript"></a>JavaScript</h4><p>和用户交互需要使用 JavaScript 来实现。我们常见的网络请求，事件处理等都有 JavaScript 来处理。关于 JavaScript 这里不做介绍了。</p><h3 id="上线"><a href="#上线" class="headerlink" title="上线"></a>上线</h3><h4 id="预览"><a href="#预览" class="headerlink" title="预览"></a>预览</h4><p>如果开发中需要预览和测试，微信需要添加相应的权限。添加预览入口：小程序管理后台 - 用户身份 – 成员管理。</p><p>添加不会推送告知被添加者。添加成功之后，使用被添加者的微信，扫描微信开发工具生成的预览二维码就可以看到开发的微信小程序了。</p><h4 id="提交审核"><a href="#提交审核" class="headerlink" title="提交审核"></a>提交审核</h4><p>开发完成，通过点击微信开发者工具右上角的上传，可以上传到小程序管理后台。在开发管理中可以找到提交的版本。这个时候的版本还是预览版本，通过扫描二维码，可以让添加权限的微信用户体验。</p><p>如果测试确认没问题可以上线，点击管理后台-开发管理中的提交审核。提交审核，第一个版本审核时间可能会有几天，之后审核时间会缩短大概一天左右。</p><h4 id="发布"><a href="#发布" class="headerlink" title="发布"></a>发布</h4><p>审核通过之后，管理员会收到微信推送。这个时候，我们的小程序还没有上线，我们可以再后天点击发布按钮来控制什么时间发布。</p><h3 id="Samples"><a href="#Samples" class="headerlink" title="Samples"></a>Samples</h3><table><thead><tr><th>官方例子</th><th>我的例子</th></tr></thead><tbody><tr><td><img src="/imgs/post/weixin_app_demo.jpg" alt="Weixin Demo"></td><td><img src="/imgs/post/wx_app_jingle1267.jpg" alt="Weixin Demo"></td></tr><tr><td>源码地址：<a href="https://github.com/jingle1267/demo" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/demo</a></td><td>源码地址：<a href="https://github.com/jingle1267/HelloCodeDev" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/HelloCodeDev</a></td></tr></tbody></table><p><br>本文地址 <a href="http://94275.cn/2018/01/10/weixin-app/">http://94275.cn/2018/01/10/weixin-app/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;微信小程序是一种全新的连接用户与服务的方式，它可以在微信内被便捷地获取和传播，同时具有出色的使用体验。&lt;/p&gt;
    
    </summary>
    
      <category term="小程序" scheme="http://94275.cn/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
    
      <category term="微信小程序" scheme="http://94275.cn/tags/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
    
  </entry>
  
  <entry>
    <title>司马懿人物关系</title>
    <link href="http://94275.cn/2018/01/09/SiMaYi/"/>
    <id>http://94275.cn/2018/01/09/SiMaYi/</id>
    <published>2018-01-09T09:39:35.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><a id="more"></a><p><img src="/imgs/post/simayi_mindmap.jpg" alt="司马懿人物关系"></p><p><a href="http://on-img.com/chart_image/5a547978e4b01acda594932b.png" rel="external nofollow noopener noreferrer" target="_blank">http://on-img.com/chart_image/5a547978e4b01acda594932b.png</a></p><p><br>本文地址 <a href="http://94275.cn/2018/01/09/SiMaYi/">http://94275.cn/2018/01/09/SiMaYi/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;
    
    </summary>
    
      <category term="历史人物" scheme="http://94275.cn/categories/%E5%8E%86%E5%8F%B2%E4%BA%BA%E7%89%A9/"/>
    
    
  </entry>
  
  <entry>
    <title>你可能不知道的毛主席</title>
    <link href="http://94275.cn/2017/12/26/Mr.-Mao/"/>
    <id>http://94275.cn/2017/12/26/Mr.-Mao/</id>
    <published>2017-12-26T02:21:48.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><a id="more"></a><p>&emsp;&emsp;这几年，国内一些对历史毫无了解的年轻人动辄喜欢拿毛主席说事，可看看仇视红色中国的美国人是怎么评价毛泽东的：</p><p>&emsp; &emsp;是谁能把一个贫瘠的国家，在短短几年的时间里，迅速崛起于世界强国的行列？事实上我记得美国以前有一位总统乔治·华盛顿。他以贫弱的美国北方军，经过多年苦战打败了先进的南方殖民军。使得美国获得了统一与和平。但是，在东方的一个大国，中国，同样出现了一位优秀的领导者：毛泽东先生。正是他领导着他的人民，在贫困，饥饿，压力下却取得了远远超越乔治·华盛顿的伟大成就…1949年，中国在毛先生领导下建立了红色政权，同时也揭开了中国人觉醒的时代。</p><p>&emsp;&emsp;1950年我们可爱的总统大人，他觉得北韩十分不听话，同时他更加厌恶新生的红色中国，为了灭绝赤祸，他决心先打掉北韩，从而占领亚洲大陆一端，再谋求最终消灭赤色中国。随即他调兵遣将， 以联合国安理会的名义，18国集团为核心，总计出兵51万3千 人。坦克2400辆。战机4000架。各型火炮5万门同时动用了原美国海军第1，2， 3，7四只舰队，排山倒海的杀向北韩。在他看来，这样现代化的庞大战斗集群，任何一个国家，哪怕是当时的苏联也不敢与之交手。然而，他似乎忘记了，那位毛先生伟大的军事战略胆量。毛在前苏联犹豫迟疑下，悍然单方面出兵抗击美国联军。于是一场惊人的战争就此爆发了。</p><p>&emsp;&emsp;100万中国士兵，在没有远程炮火支援，没有空中火力掩护，没有地面装甲集群突击的情况下，依靠着最原始的卡宾枪（冲锋枪），手雷。打败了强大的美国联军。这也是人类历史上，首次开创了一个国家单独击败了世界力量的先例。但是，中国人也遭受了525000人的惨烈伤亡。但是对于一个几年前还被日本军队肆意侵略蹂躏的国家，在短短几年后，突然间打败了世界上当时最强军事同盟“北大西洋公约组织”的奇迹除了毛先生敢于创造， 任何人都不可能做到。 美国就这样丢下了113000名阵亡士兵，带着84000名伤员，以及换回来的45000名被俘人员迈着沉重的脚步，蹒跚的回到了自己的老家。</p><p>&emsp;&emsp;前苏联的伟大人物赫鲁晓夫先生，上台后，他觉得中共的毛太不懂得什么叫尊重苏联，竟敢违背他的指令。因此，他发动了一 场更加荒谬的战役——中苏珍宝岛战役。苏军以远东集团军的1个坦克旅，3个摩托化步兵团，总计约20000人在没有事先警告的情况下对中国采取了军事行动。而中国当时最强的主战坦克T59 型也就是前苏联的T54A。战斗全重只有36吨。如果与前苏联最新的T62型坦克对比， 可以说对方无需开火，使用自身就可以将T59 撞翻。 毛先生在接到边防军告警电报后， 他做出了最快决定：打！就把他打疼！结果苏联人丢下了约1个团的装备以及成批尸体气恼的回家去了。 赫鲁晓夫接到失败的电报后，召开了紧急军事会议，先后撤职了隶属于苏联远东集团军1位元帅（坦克装甲诸兵种元帅），3名大将，四名上将，24名中将、少将。抓捕了远东红旗134师（主力师）营级以上全部军事主官。</p><p>&emsp;&emsp;在毛先生对外战争历史中，还有一场值得提起，那就是中印边界之战：麦克马洪线。 印度为了夺取那块不毛之地，与中国军队公然交手。其实在印度背后有输了韩战无处撒气的华盛顿，有丢了珍宝岛满脸怒火的克里姆林宫。有祈求可以捞足好处的大英帝国等等。他们几乎出现了前所未有的合作！ 苏联低价贷款给印度尼赫鲁，装备了7个印度陆军师。华盛顿给了尼赫鲁大批战备物资。英国把自己的那些老式火炮都给了印度。一时间印度成了当时世界两大集团的宠儿。 但是，短短的30天时间，印度军队全军溃败。当时在第2师作战术指挥教导的洛克．弗菲希尔准将说：你见过非洲的斑马群奔跑吗？但是不如印度军队溃逃更加壮观。 8940名印度军人葬身山谷，1370名士兵被俘，1名准将被击毙，亚洲第一旅：“锡克”旅完了。英国全资资助“廓尔柯”营完了。而毛先生在他的官邸中南海，战前就曾说：不管你是印苏联军，还是美印联军，即便是再来一次八国联军我们中国也要与你们打！打出一个真理来。 毛先生的英明是前所未有的。中国拿回来了土地，消灭了印度联军，打败了美国与苏联的再一次的恐吓，这就是毛先生。</p><p>&emsp;&emsp;毛先生一贯坚持自力更生，也是由于他的如此英明，中国建立了自己的核武器工业。制造远程洲际导弹。可是今天的中国人，是不是还都记得我们这位罕见的民族伟人呢？ ……看过之后让人肃然起敬！让我们一起动手，把这篇文章传播出去了，让我们的后代，永远记得这位伟人！ 喜欢的就转一下，至少我很愿意再看一遍。</p><p>&emsp;&emsp;12月26日毛先生的生日，中国人的圣诞节！</p><p><br>本文地址 <a href="http://94275.cn/2017/12/26/Mr.-Mao/">http://94275.cn/2017/12/26/Mr.-Mao/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Android Architecture Components之LiveData</title>
    <link href="http://94275.cn/2017/12/14/Android-LiveData/"/>
    <id>http://94275.cn/2017/12/14/Android-LiveData/</id>
    <published>2017-12-14T09:40:07.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>LiveData 是一个数据持有者类，它持有一个值并允许观察该值。不同于普通的可观察者，LiveData 遵守应用程序组件的生命周期，以便 Observer 可以指定一个其应该遵守的 Lifecycle。</p><a id="more"></a><p>LiveData实现了对数据的监听，利用这点，我们可以更好的实现获取数据和数据展示解耦。本文着重讲解数据更新和更新UI逻辑分离，LiveData的LifeCycle特性暂不做介绍。</p><p>下文用一个简单的例子来介绍如何实现数据更新和UI展示解耦，实现逻辑分离。</p><p>UI展示逻辑代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> MutableLiveData&lt;String&gt; username;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> TextView tvUsername;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">        setContentView(R.layout.activity_live_data);</span><br><span class="line"></span><br><span class="line">        tvUsername = findViewById(R.id.tv_username);</span><br><span class="line"></span><br><span class="line">        username = <span class="keyword">new</span> MutableLiveData&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        username.observe(<span class="keyword">this</span>, <span class="keyword">new</span> Observer&lt;String&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onChanged</span><span class="params">(@Nullable String s)</span> </span>&#123;</span><br><span class="line">                tvUsername.setText(s);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>上面代码对应的布局文件代码如下：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">LinearLayout</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:orientation</span>=<span class="string">"vertical"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">tools:context</span>=<span class="string">"com.ihognqiqu.aac.livedata.LiveDataActivity"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">TextView</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/tv_username"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:padding</span>=<span class="string">"40dp"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:text</span>=<span class="string">"Default User Name"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:textSize</span>=<span class="string">"20dp"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">Button</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/tv_change_username"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:onClick</span>=<span class="string">"onClickMainThread"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:text</span>=<span class="string">"Change User Name main thread"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">Button</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/tv_change_username_background"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:onClick</span>=<span class="string">"onClickThread"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:text</span>=<span class="string">"Change User Name background"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">TextView</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_marginTop</span>=<span class="string">"10dp"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:padding</span>=<span class="string">"10dp"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:text</span>=<span class="string">"一个数据持有类，持有数据并且这个数据可以被观察被监听，和其他Observer不同的是，它和Lifecycle是绑定的。"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:textColor</span>=<span class="string">"@color/colorPrimary"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:textSize</span>=<span class="string">"17dp"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">LinearLayout</span>&gt;</span></span><br></pre></td></tr></table></figure><p>从上面代码可以发现，除了基本的初始化操作、设置监听，只剩下UI赋值逻辑。</p><p>主线程更新数据代码（点击id为tv_change_username的按钮执行下面的方法）：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 主线程中更新数据</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span> view</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClickMainThread</span><span class="params">(View view)</span> </span>&#123;</span><br><span class="line">     username.setValue(<span class="string">"New User Name by main thread"</span>);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>子线程更新数据代码如下（点击id为tv_change_username_background的按钮执行下面这个方法）：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 子线程中更新数据</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span> view</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClickThread</span><span class="params">(View view)</span> </span>&#123;</span><br><span class="line">     <span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">         <span class="meta">@Override</span></span><br><span class="line">         <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">             <span class="keyword">try</span> &#123;</span><br><span class="line">                 Thread.sleep(<span class="number">2000</span>);</span><br><span class="line">             &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                 e.printStackTrace();</span><br><span class="line">             &#125;</span><br><span class="line">             username.postValue(<span class="string">"New User Name by background thread"</span>);</span><br><span class="line">         &#125;</span><br><span class="line">     &#125;).start();</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>从上面同步和异步两个方法，可以发现这里只有对数据的更新逻辑，没有任何UI更新的逻辑。</p><p>例子很简单，通过使用LiveData，我们实现了业务逻辑和UI更新逻辑分离。通过使用LiveData可以使我们的架构设计更加合理，职责分工更加明确。从小的方面来看，实现了解耦代码分离，从大的方面说，这会改变应用架构设计。</p><p>参考地址：<a href="https://developer.android.com/topic/libraries/architecture/livedata.html" rel="external nofollow noopener noreferrer" target="_blank">https://developer.android.com/topic/libraries/architecture/livedata.html</a><br>源码地址：<a href="https://github.com/jingle1267/AndroidArchitectureComponets" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/AndroidArchitectureComponets</a></p><p><br>本文地址 <a href="http://94275.cn/2017/12/14/Android-LiveData/">http://94275.cn/2017/12/14/Android-LiveData/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;LiveData 是一个数据持有者类，它持有一个值并允许观察该值。不同于普通的可观察者，LiveData 遵守应用程序组件的生命周期，以便 Observer 可以指定一个其应该遵守的 Lifecycle。&lt;/p&gt;
    
    </summary>
    
      <category term="Android Architecture Components" scheme="http://94275.cn/categories/Android-Architecture-Components/"/>
    
    
      <category term="LiveData" scheme="http://94275.cn/tags/LiveData/"/>
    
  </entry>
  
  <entry>
    <title>Android Architecture Components之LifeCycle</title>
    <link href="http://94275.cn/2017/12/09/lifecycle/"/>
    <id>http://94275.cn/2017/12/09/lifecycle/</id>
    <published>2017-12-09T08:13:44.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>LifeCycle 架构设计一大利器，旨在减少Activity和Fragment中代码，简化Activity和Fragment职责，实现功能代码分离，达到解耦的目的。</p><a id="more"></a><p>官方解释：</p><p><em>Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.</em></p><p>译文：Lifecycle-aware 组件感知Activity和Fragment的周明周期，并能响应个生命周期状态。这个组件有助于产生更有序、更轻和更易维护的代码。</p><h3 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h3><p>LifeCycle作用主要是针对开发中遇到的一些痛点，它的优点也是基于现有的痛点，主要以下有点：</p><ol><li>减轻acitivity和fragment的负担，实现调用方代码更加更加简洁</li><li>为封装组件提供更好的支持，达到组件独立，实现更好的内聚和更低的耦合</li><li>复用变得更加简单</li><li>实现组合优于继承的设计思想</li></ol><h3 id="没有LifeCycle的时候"><a href="#没有LifeCycle的时候" class="headerlink" title="没有LifeCycle的时候"></a>没有LifeCycle的时候</h3><p>没有LifeCycle组件的时候，我们实现一个定位功能通常会如下实现：</p><p>主程序代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 定位功能一般实现方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LocationActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> LocationListener mLocationListener;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">        setContentView(R.layout.activity_location);</span><br><span class="line">        mLocationListener = <span class="keyword">new</span> LocationListener();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onStart</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onStart();</span><br><span class="line">        <span class="keyword">if</span> (mLocationListener != <span class="keyword">null</span>) &#123;</span><br><span class="line">            mLocationListener.start();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onStop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onStop();</span><br><span class="line">        <span class="keyword">if</span> (mLocationListener != <span class="keyword">null</span>) &#123;</span><br><span class="line">            mLocationListener.stop();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>定位逻辑实现如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LocationListener</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">start</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Log.d(<span class="string">"LifeCycleListener"</span>, <span class="string">"start"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">stop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Log.d(<span class="string">"LifeCycleListener"</span>, <span class="string">"stop"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>从上面的代码，可以发现，实现一个定位，我们需要在activity和fragment处理打开定位和关闭定位。这只是一个定位，在现实开发中，我们会有统计等很多类似的功能，这样我们的activity和fragment代码会变得臃肿，且代码不易复用。</p><h3 id="使用LifeCycle后"><a href="#使用LifeCycle后" class="headerlink" title="使用LifeCycle后"></a>使用LifeCycle后</h3><p>在我们使用LifeCycle之后，主程序如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LifeCycleActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">        setContentView(R.layout.activity_life_cycle);</span><br><span class="line"></span><br><span class="line">        getLifecycle().addObserver(<span class="keyword">new</span> LocationListener());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>定位逻辑如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 跟生命周期相关的监听器</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Created by zhenguo on 12/5/17.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LocationListener</span> <span class="keyword">implements</span> <span class="title">LifecycleObserver</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@OnLifecycleEvent</span>(Lifecycle.Event.ON_START)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">start</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Log.d(<span class="string">"LifeCycleListener"</span>, <span class="string">"start"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@OnLifecycleEvent</span>(Lifecycle.Event.ON_STOP)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">stop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Log.d(<span class="string">"LifeCycleListener"</span>, <span class="string">"stop"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@OnLifecycleEvent</span>(Lifecycle.Event.ON_ANY)</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">onAny</span><span class="params">(LifecycleOwner owner, Lifecycle.Event event)</span> </span>&#123;</span><br><span class="line">        Log.d(<span class="string">"LifeCycleListener"</span>, <span class="string">"onAny:"</span> + event.name());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>显而易见，现在调用程序只需一行代码，简化了调用方的代码，调用方不需要关心生命周期的处理逻辑，这部分逻辑转移到具体的业务实现方，实现高内聚和低耦合。</p><h3 id="参考地址"><a href="#参考地址" class="headerlink" title="参考地址"></a>参考地址</h3><p>官方地址：<a href="https://developer.android.com/topic/libraries/architecture/lifecycle.html" rel="external nofollow noopener noreferrer" target="_blank">https://developer.android.com/topic/libraries/architecture/lifecycle.html</a><br>源码地址：<a href="https://github.com/jingle1267/AndroidArchitectureComponets" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/AndroidArchitectureComponets</a></p><p><br>本文地址 <a href="http://94275.cn/2017/12/09/lifecycle/">http://94275.cn/2017/12/09/lifecycle/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;LifeCycle 架构设计一大利器，旨在减少Activity和Fragment中代码，简化Activity和Fragment职责，实现功能代码分离，达到解耦的目的。&lt;/p&gt;
    
    </summary>
    
      <category term="Android Architecture Components" scheme="http://94275.cn/categories/Android-Architecture-Components/"/>
    
    
      <category term="LifeCycle" scheme="http://94275.cn/tags/LifeCycle/"/>
    
  </entry>
  
  <entry>
    <title>我在做一个APP中用到的开源库</title>
    <link href="http://94275.cn/2017/11/29/Common-Android-Open-Source-Project/"/>
    <id>http://94275.cn/2017/11/29/Common-Android-Open-Source-Project/</id>
    <published>2017-11-29T07:27:34.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>最近开发了一个APP，虽然是一个小APP，但是麻雀虽小五脏俱全。以下简单介绍一下用到的开源组件。</p><a id="more"></a><h3 id="功能类"><a href="#功能类" class="headerlink" title="功能类"></a>功能类</h3><ol><li><a href="https://github.com/JakeWharton/butterknife" rel="external nofollow noopener noreferrer" target="_blank">ButterKnife</a></li><li><a href="https://github.com/rzwitserloot/lombok" rel="external nofollow noopener noreferrer" target="_blank">Lombok</a></li><li><a href="https://github.com/jingle1267/android-utils" rel="external nofollow noopener noreferrer" target="_blank">android-utils</a></li><li><a href="https://github.com/realm/realm-java" rel="external nofollow noopener noreferrer" target="_blank">realm-java</a></li><li><a href="https://github.com/jingle1267/AndroidRequest" rel="external nofollow noopener noreferrer" target="_blank">AndroidRequest</a></li><li><a href="https://github.com/ReactiveX/RxAndroid" rel="external nofollow noopener noreferrer" target="_blank">RxAndroid</a></li></ol><h4 id="ButterKnife"><a href="#ButterKnife" class="headerlink" title="ButterKnife"></a>ButterKnife</h4><p>自从用上Butter Knife，再也不用findViewById这种代码了。Android界JakeWharton大神出品，必属精品，强烈推荐使用。<br>Github地址：<a href="https://github.com/JakeWharton/butterknife" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/JakeWharton/butterknife</a><br>使用文档：<a href="http://jakewharton.github.io/butterknife/" rel="external nofollow noopener noreferrer" target="_blank">http://jakewharton.github.io/butterknife/</a></p><h4 id="Lombok"><a href="#Lombok" class="headerlink" title="Lombok"></a>Lombok</h4><p>自从使用了Lombok，实体类告别了大段大段的set/get方法。简简单单的一行注解，告别成百上千行的实体类。<br>Github地址：<a href="https://github.com/rzwitserloot/lombok" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/rzwitserloot/lombok</a><br>视频演示地址：<a href="https://projectlombok.org/" rel="external nofollow noopener noreferrer" target="_blank">https://projectlombok.org/</a><br>接入文档：<a href="https://projectlombok.org/setup/android" rel="external nofollow noopener noreferrer" target="_blank">https://projectlombok.org/setup/android</a></p><h4 id="android-utils"><a href="#android-utils" class="headerlink" title="android-utils"></a>android-utils</h4><p>开发过程中，工具类必不可少。自从用了android-utils，大大方便了开发，节省了自己开发时间。<br>Github地址：<a href="https://github.com/jingle1267/android-utils" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/android-utils</a></p><h4 id="realm-java"><a href="#realm-java" class="headerlink" title="realm-java"></a>realm-java</h4><p>Realm为移动设备而生！替代 SQLite 和 Core Data。为你省下数周的时间和数千行的代码，帮你创造出更棒的用户体验。</p><p>Github地址：<a href="https://github.com/realm/realm-java" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/realm/realm-java</a><br>使用文档：<a href="https://realm.io/cn/docs/java/latest/" rel="external nofollow noopener noreferrer" target="_blank">https://realm.io/cn/docs/java/latest/</a></p><h4 id="AndroidRequest"><a href="#AndroidRequest" class="headerlink" title="AndroidRequest"></a>AndroidRequest</h4><p>基于retrofit和okhttp封装的网络库，用户不需要了解网络底层实现，通过简单的设置就能实现网络请求。</p><p>Github地址：<a href="https://github.com/jingle1267/AndroidRequest" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/jingle1267/AndroidRequest</a></p><h4 id="RxAndroid"><a href="#RxAndroid" class="headerlink" title="RxAndroid"></a>RxAndroid</h4><p>RxAndroid是RxJava的扩展, 可以优雅地处理异步请求。很好很强大！</p><p>GitHub 地址：<a href="https://github.com/ReactiveX/RxAndroid" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/ReactiveX/RxAndroid</a></p><h3 id="UI交互类"><a href="#UI交互类" class="headerlink" title="UI交互类"></a>UI交互类</h3><ol><li><a href="https://github.com/lcodecorex/TwinklingRefreshLayout" rel="external nofollow noopener noreferrer" target="_blank">TwinklingRefreshLayout</a></li><li><a href="https://github.com/bumptech/glide" rel="external nofollow noopener noreferrer" target="_blank">Glide</a></li><li><a href="https://github.com/ikew0ng/SwipeBackLayout" rel="external nofollow noopener noreferrer" target="_blank">SwipeBackLayout</a></li><li><a href="https://github.com/zhihu/Matisse" rel="external nofollow noopener noreferrer" target="_blank">Matisse</a></li><li><a href="https://github.com/hdodenhof/CircleImageView" rel="external nofollow noopener noreferrer" target="_blank">CircleImageView</a></li><li><a href="https://github.com/H07000223/FlycoTabLayout" rel="external nofollow noopener noreferrer" target="_blank">FlycoTabLayout</a></li><li><a href="https://github.com/7heaven/SHSegmentControl" rel="external nofollow noopener noreferrer" target="_blank">SHSegmentControl</a></li><li><a href="https://github.com/google/flexbox-layout" rel="external nofollow noopener noreferrer" target="_blank">flexbox-layout</a></li><li><a href="https://github.com/yanzhenjie/Album" rel="external nofollow noopener noreferrer" target="_blank">Album</a></li><li><a href="https://github.com/MagicMashRoom/SuperCalendar" rel="external nofollow noopener noreferrer" target="_blank">SuperCalendar</a></li><li><a href="https://github.com/fython/MaterialStepperView" rel="external nofollow noopener noreferrer" target="_blank">MaterialStepperView</a></li></ol><h4 id="TwinklingRefreshLayout"><a href="#TwinklingRefreshLayout" class="headerlink" title="TwinklingRefreshLayout"></a>TwinklingRefreshLayout</h4><p>支持下拉刷新和上拉加载的RefreshLayout,自带越界回弹效果，支持RecyclerView,AbsListView,ScrollView,WebView。</p><p>Github地址：<a href="https://github.com/lcodecorex/TwinklingRefreshLayout" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/lcodecorex/TwinklingRefreshLayout</a></p><h4 id="Glide"><a href="#Glide" class="headerlink" title="Glide"></a>Glide</h4><p>Google推荐的图片加载库，专注于流畅的滚动。</p><p>Github地址：<a href="https://github.com/bumptech/glide" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/bumptech/glide</a></p><h4 id="SwipeBackLayout"><a href="#SwipeBackLayout" class="headerlink" title="SwipeBackLayout"></a>SwipeBackLayout</h4><p>类似微信的右滑关闭页面，本开源库支持右滑、左滑、上滑手势</p><p>Github地址：<a href="https://github.com/ikew0ng/SwipeBackLayout" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/ikew0ng/SwipeBackLayout</a></p><h4 id="Matisse"><a href="#Matisse" class="headerlink" title="Matisse"></a>Matisse</h4><p>一个设计良好的本地图片／视频文件选择库，支持不同的图片加载方式。知乎出品，也是精品。</p><p>Github地址：<a href="https://github.com/zhihu/Matisse" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/zhihu/Matisse</a></p><h4 id="CircleImageView"><a href="#CircleImageView" class="headerlink" title="CircleImageView"></a>CircleImageView</h4><p>圆形图片，边框等，简单易用。</p><p>Github地址：<a href="https://github.com/hdodenhof/CircleImageView" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/hdodenhof/CircleImageView</a></p><h4 id="FlycoTabLayout"><a href="#FlycoTabLayout" class="headerlink" title="FlycoTabLayout"></a>FlycoTabLayout</h4><p>Tab切换通用样式。</p><p>Github地址：<a href="https://github.com/H07000223/FlycoTabLayout" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/H07000223/FlycoTabLayout</a></p><h4 id="SHSegmentControl"><a href="#SHSegmentControl" class="headerlink" title="SHSegmentControl"></a>SHSegmentControl</h4><p>仿iOS的Tag切换效果。</p><p>Github地址：<a href="https://github.com/7heaven/SHSegmentControl" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/7heaven/SHSegmentControl</a></p><h4 id="flexbox-layout"><a href="#flexbox-layout" class="headerlink" title="flexbox-layout"></a>flexbox-layout</h4><p>谷歌官方流式布局，功能强大。</p><p>Github地址：<a href="https://github.com/google/flexbox-layout" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/google/flexbox-layout</a></p><h4 id="Album"><a href="#Album" class="headerlink" title="Album"></a>Album</h4><p>Album是一个MD风格的开源相册，支持国际化，支持国际化扩展；主要功能模块：选择图片与视频、拍照、录视频、画廊。</p><p>Github地址：<a href="https://github.com/yanzhenjie/Album" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/yanzhenjie/Album</a></p><h4 id="SuperCalendar"><a href="#SuperCalendar" class="headerlink" title="SuperCalendar"></a>SuperCalendar</h4><p>日历选择控件，代码简洁。自定义日历控件 支持左右无限滑动 周月切换 标记日期显示 自定义显示效果跳转到指定日期。</p><p>Github地址：<a href="https://github.com/MagicMashRoom/SuperCalendar" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/MagicMashRoom/SuperCalendar</a></p><h4 id="MaterialStepperView"><a href="#MaterialStepperView" class="headerlink" title="MaterialStepperView"></a>MaterialStepperView</h4><p>带动画效果的步骤控件。</p><p>Github地址：<a href="https://github.com/fython/MaterialStepperView" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/fython/MaterialStepperView</a></p><p><br>本文地址 <a href="http://94275.cn/2017/11/29/Common-Android-Open-Source-Project/">http://94275.cn/2017/11/29/Common-Android-Open-Source-Project/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;最近开发了一个APP，虽然是一个小APP，但是麻雀虽小五脏俱全。以下简单介绍一下用到的开源组件。&lt;/p&gt;
    
    </summary>
    
      <category term="开源库" scheme="http://94275.cn/categories/%E5%BC%80%E6%BA%90%E5%BA%93/"/>
    
    
      <category term="开源库" scheme="http://94275.cn/tags/%E5%BC%80%E6%BA%90%E5%BA%93/"/>
    
  </entry>
  
  <entry>
    <title>RxJava Hello World</title>
    <link href="http://94275.cn/2017/10/16/RxJava-Hello-World/"/>
    <id>http://94275.cn/2017/10/16/RxJava-Hello-World/</id>
    <published>2017-10-16T10:02:03.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><h4 id="RxJava是什么？"><a href="#RxJava是什么？" class="headerlink" title="RxJava是什么？"></a>RxJava是什么？</h4><blockquote><p>RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.</p></blockquote><p>翻译:一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。RxJava官方地址：<a href="https://github.com/ReactiveX/RxJava" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/ReactiveX/RxJava</a></p><a id="more"></a><h4 id="RxJava解决了什么问题？"><a href="#RxJava解决了什么问题？" class="headerlink" title="RxJava解决了什么问题？"></a>RxJava解决了什么问题？</h4><p>RxJava近两年来越来越流行，越来越收到广大开发者青睐，肯定它有哪些魔力。这魔力解决了开发者开发过程中的某些痛点，结合对RxJava的理解，你会发现，其实它解决的是<strong>异步</strong>的问题。</p><p>RxJava是如何解决异步处理的问题的呢？开发中异步的主要场景时，耗时操作需要放到单独线程中，异步任务执行成功之后，在主线程中执行更新UI等其它操作。</p><p>使用RxJava之后，通过简单设置，就可以实现执行线程的切换，开发者只需要关心具体的逻辑，不用太多关心那个线程的问题。</p><h4 id="Hello-World"><a href="#Hello-World" class="headerlink" title="Hello World"></a>Hello World</h4><p>下面举一个异步下载图片，主线程更新显示出来的例子（例子用Android实现）:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">String url = <span class="string">"https://avatars2.githubusercontent.com/u/3887795?v=2&amp;s=60"</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1.将网络地址转换为Drawable</span></span><br><span class="line">Function&lt;String, Drawable&gt; str2Drawable = <span class="keyword">new</span> Function&lt;String, Drawable&gt;() &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Drawable <span class="title">apply</span><span class="params">(@NonNull String s)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        Drawable drawable = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            drawable = Drawable.createFromStream(<span class="keyword">new</span> URL(s).openStream(), <span class="string">"src"</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> drawable;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.将drawable先是到imageview上</span></span><br><span class="line">Consumer&lt;Drawable&gt; drawableConsumer = <span class="keyword">new</span> Consumer&lt;Drawable&gt;() &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(Drawable drawable)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        ivWebPic.setImageDrawable(drawable);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.控制步骤1和步骤2执行线程</span></span><br><span class="line">Observable.just(url)</span><br><span class="line">        .map(str2Drawable)</span><br><span class="line">        .subscribeOn(Schedulers.io())</span><br><span class="line">        .observeOn(AndroidSchedulers.mainThread())</span><br><span class="line">        .subscribe(drawableConsumer);</span><br></pre></td></tr></table></figure><p>以上代码，下载图片逻辑和展示逻辑完全分离，实现逻辑分离。这只是一个Hello World例子，RxJava很有很多炫酷的功能期待你去解锁。</p><p><br>本文地址 <a href="http://94275.cn/2017/10/16/RxJava-Hello-World/">http://94275.cn/2017/10/16/RxJava-Hello-World/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;h4 id=&quot;RxJava是什么？&quot;&gt;&lt;a href=&quot;#RxJava是什么？&quot; class=&quot;headerlink&quot; title=&quot;RxJava是什么？&quot;&gt;&lt;/a&gt;RxJava是什么？&lt;/h4&gt;&lt;blockquote&gt;&lt;p&gt;RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;翻译:一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。RxJava官方地址：&lt;a href=&quot;https://github.com/ReactiveX/RxJava&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://github.com/ReactiveX/RxJava&lt;/a&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="RxJava" scheme="http://94275.cn/categories/RxJava/"/>
    
    
      <category term="RxJava" scheme="http://94275.cn/tags/RxJava/"/>
    
  </entry>
  
  <entry>
    <title>BottomNavigationView</title>
    <link href="http://94275.cn/2017/06/14/BottomNavigationView/"/>
    <id>http://94275.cn/2017/06/14/BottomNavigationView/</id>
    <published>2017-06-14T14:35:22.000Z</published>
    <updated>2024-06-15T15:24:16.181Z</updated>
    
    <content type="html"><![CDATA[<!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --><p>要点：本文主要写使用 BottomNavigationView 和遇到的一些问题的解决办法</p><a id="more"></a><h3 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h3><p>作为谷歌 <a href="https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html" rel="external nofollow noopener noreferrer" target="_blank">Material Design Components</a> 新控件 BottomNavigationView， 提供应用底部导航栏的实现。没有这个控件之前，Android 底部导航栏一般通过 LinearLayout 包裹几个 Button 或使用 RadioGroup 和 RadioButton 来实现。使用 BottomNavigationView 这个控件，可以提供更好的用户体验和开发更容易。此文主要介绍在使用 BottomNavigationView 过程中遇到的几个问题。</p><h3 id="如何使用"><a href="#如何使用" class="headerlink" title="如何使用"></a>如何使用</h3><h4 id="添加依赖"><a href="#添加依赖" class="headerlink" title="添加依赖"></a>添加依赖</h4><p>这个没有什么好说的</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compile 'com.android.support:design:25.0.0'</span><br></pre></td></tr></table></figure><h4 id="添加布局"><a href="#添加布局" class="headerlink" title="添加布局"></a>添加布局</h4><p>布局分两个部分，首先是总的布局：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">android.support.design.widget.BottomNavigationView</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:itemIconTint</span>=<span class="string">"@color/tab_home"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:itemTextColor</span>=<span class="string">"@color/tab_home"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_gravity</span>=<span class="string">"bottom"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:background</span>=<span class="string">"?android:attr/windowBackground"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:menu</span>=<span class="string">"@menu/navigation"</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>其次，配置导航项。在 res 的 menu 目录下创建上面代码中 app:menu=”@menu/bottom_menu” 要引用到的文件：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">menu</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">item</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation_home"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_home"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:title</span>=<span class="string">"@string/title_home"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">item</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation_category"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_category"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:title</span>=<span class="string">"@string/title_category"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">item</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation_activity"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_activity"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:title</span>=<span class="string">"@string/title_activity"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">item</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation_cart"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_cart"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:title</span>=<span class="string">"@string/title_cart"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">item</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">"@+id/navigation_mine"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:icon</span>=<span class="string">"@drawable/ic_mine"</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:title</span>=<span class="string">"@string/title_mine"</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">menu</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="事件处理"><a href="#事件处理" class="headerlink" title="事件处理"></a>事件处理</h4><p>主要是点击事件的处理，代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">navigation = (BottomNavigationView) findViewById(R.id.navigation);</span><br><span class="line">        navigation.setOnNavigationItemSelectedListener(<span class="keyword">new</span> BottomNavigationView.OnNavigationItemSelectedListener() &#123;</span><br><span class="line"></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onNavigationItemSelected</span><span class="params">(@NonNull MenuItem item)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">switch</span> (item.getItemId()) &#123;</span><br><span class="line">                    <span class="keyword">case</span> R.id.navigation_home:</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                    <span class="keyword">case</span> R.id.navigation_category:</span><br><span class="line">                        setTitle(R.string.title_category);</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                    <span class="keyword">case</span> R.id.navigation_activity:</span><br><span class="line">                        setTitle(R.string.title_activity);</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                    <span class="keyword">case</span> R.id.navigation_cart:</span><br><span class="line">                        setTitle(R.string.title_cart);</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                    <span class="keyword">case</span> R.id.navigation_mine:</span><br><span class="line">                        setTitle(R.string.title_mine);</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br></pre></td></tr></table></figure><p>通过以上的代码，我们的代码就能运行起来，效果图如下:<img src="/imgs/post/bottomnavigation_example_1.png" alt="bottomnavigation_example_1">：</p><h3 id="没那么简单"><a href="#没那么简单" class="headerlink" title="没那么简单"></a>没那么简单</h3><p>很快你会发现，接入简单，但是真正符合我们的设计要求，我们还需要捣腾捣腾。</p><p>下面列举一下我遇到的问题：</p><ol><li>当导航项大于三个的时候，选中项变大，其它文字被隐藏</li><li><p>当我们自定义默认和选中图之后，选中的效果图变色了</p><p>问题来了，我们怎么解决呢？</p><p>针对第一个问题，在网上查资料后，发现是 mShiftingMode 的问题，默认是开启的且谷歌没有开放修改接口。既然谷歌不给修改接口，那么我们就硬来，用反射来解决。实现代码如下：</p></li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">BottomNavigationViewHelper.disableShiftMode(navigation);</span><br></pre></td></tr></table></figure><p>BottomNavigationViewHelper 代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BottomNavigationViewHelper</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">disableShiftMode</span><span class="params">(BottomNavigationView view)</span> </span>&#123;</span><br><span class="line">        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Field shiftingMode = menuView.getClass().getDeclaredField(<span class="string">"mShiftingMode"</span>);</span><br><span class="line">            shiftingMode.setAccessible(<span class="keyword">true</span>);</span><br><span class="line">            shiftingMode.setBoolean(menuView, <span class="keyword">false</span>);</span><br><span class="line">            shiftingMode.setAccessible(<span class="keyword">false</span>);</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; menuView.getChildCount(); i++) &#123;</span><br><span class="line">                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);</span><br><span class="line">                item.setShiftingMode(<span class="keyword">false</span>);</span><br><span class="line">                item.setChecked(item.getItemData().isChecked());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoSuchFieldException e) &#123;</span><br><span class="line">            Log.e(<span class="string">"BottomNavigationViewHelper"</span>, <span class="string">"Unable to get shift mode field"</span>, e);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IllegalAccessException e) &#123;</span><br><span class="line">            Log.e(<span class="string">"BottomNavigationViewHelper"</span>, <span class="string">"Unable to change value of shift mode"</span>, e);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>针对第二个问题，各种谷歌百度后，发现是控件默认着色器的问题。知道问题所在，解决起来就简单了。只需一行代码禁 tint 就好了</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">navigation.setItemIconTintList(<span class="keyword">null</span>);</span><br></pre></td></tr></table></figure><p>默认和选中文字的颜色，只需要添加颜色 selector 就可以了</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app:itemTextColor="@color/tab_home"</span><br></pre></td></tr></table></figure><p>另外，BottomNavigationView 支持的导航项数量是3-5个。</p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>谷歌 BottomNavigationView 效果是挺好的，使用很方便，特效也很不错，唯一不足就是接口不太友善。总的来说，这个控件使用容易且效果很赞，建议使用。</p><p><br>本文地址 <a href="http://94275.cn/2017/06/14/BottomNavigationView/">http://94275.cn/2017/06/14/BottomNavigationView/</a> 作者为<a href="/about/"> Zhenguo</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Sat Jun 15 2024 15:24:54 GMT+0000 (UTC) --&gt;&lt;p&gt;要点：本文主要写使用 BottomNavigationView 和遇到的一些问题的解决办法&lt;/p&gt;
    
    </summary>
    
      <category term="Android" scheme="http://94275.cn/categories/Android/"/>
    
    
      <category term="BottomNavigationView" scheme="http://94275.cn/tags/BottomNavigationView/"/>
    
  </entry>
  
</feed>
