转自:http://blog.youkuaiyun.com/a553181867/article/details/51431393
本文讲主要来说说Toolbar、RecyclerView、CardView、DrawerLayout、以及SwiperefreshLayout的综合使用,其中Toolbar和RecyclerView在前几篇博客已经详细讲述其用法了,有兴趣的可以去看看。现在利用这几个控件实现Material Design风格的知乎主页(Android v3.3版 知乎),在讲到相关控件的时候,我也会提及一下这个控件的用法。那么,让我们开始控件之旅吧。
示例效果
在动手写代码之前,我们先要看看最终的实现效果是什么:
首先,顶部导航栏是Toolbar,下面是RecyclerView,而RecyclerView内部的item view则是一个个CardView。
接着,向右滑动,会出现一个侧边菜单栏,这个是用DrawerLayout实现的,下面会详细说明。
最后,还实现了下拉刷新功能,这个是用SwiperefreshLayout实现的。
以上效果大致和手机上的知乎效果一样(v3.3版),但最新的知乎已经更新到了4.0,改动很多,就不是以上的效果了。但无碍我们接下来的学习。
动手实践
part 1.侧滑菜单的布局:DrawerLayout
根据以上的效果,我们首先要创建一个DrawerLayout布局,它是一个ViewGroup,因此能放下其他的View,显然左边滑出来的部分放我们的侧滑菜单选项,而右边则是我们的主页部分,新建activity_main.xml文件:
<code class="language-xml hljs has-numbering"><span class="hljs-tag"><<span class="hljs-title">android.support.v4.widget.DrawerLayout </span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/drawer_layout"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span> <span class="hljs-comment"><!-- main content --></span> <span class="hljs-tag"><<span class="hljs-title">include</span> <span class="hljs-attribute">layout</span>=<span class="hljs-value">"@layout/content_main"</span>></span><span class="hljs-tag"></<span class="hljs-title">include</span>></span> <span class="hljs-comment"><!-- The navigation drawer--></span> <span class="hljs-tag"><<span class="hljs-title">include</span> <span class="hljs-attribute">layout</span>=<span class="hljs-value">"@layout/drawermenu"</span>></span><span class="hljs-tag"></<span class="hljs-title">include</span>></span> <span class="hljs-tag"></<span class="hljs-title">android.support.v4.widget.DrawerLayout</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul>
这里简单介绍一下DrawerLayout的用法:在布局内部放两个子布局,分别是content_main和drawermenu,放在上面的布局会默认显示为主页,而下面的布局则会隐藏,需要滑动才能显示。因此,主页的view一般放在drawerlayout的第一个子View位置,同时宽高设置应为match_parent。而侧滑菜单的高度为match_parent,但宽度应该设置为一个固定的值(一般侧滑菜单不会完全覆盖主内容),同时它的layout_gravity要指定一个值,比如本例,是从左滑出的,因此要设置为android:layout_gravity=”left”,表示在父布局的左侧,否则会失去侧滑的效果。更多DrawerLayout的具体使用方法可以参考安卓官方指南:Creating a Navigation Drawer。
Part 2.侧滑菜单:ListView
为了方便起见,侧滑菜单采用了listView的列表呈现,新建drawermenu.xml文件,代码如下:
<code class="language-xml hljs has-numbering"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag"><<span class="hljs-title">RelativeLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_gravity</span>=<span class="hljs-value">"left"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#ffffff"</span>></span> <span class="hljs-tag"><<span class="hljs-title">LinearLayout </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/admininfo"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#58a5ff"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span>></span> <span class="hljs-tag"><<span class="hljs-title">ImageView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/adminicon"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"80dp"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"80dp"</span> <span class="hljs-attribute">android:layout_margin</span>=<span class="hljs-value">"5dp"</span> <span class="hljs-attribute">android:src</span>=<span class="hljs-value">"@mipmap/ic_usericon"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/adminname"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_margin</span>=<span class="hljs-value">"5dp"</span> <span class="hljs-attribute">android:paddingLeft</span>=<span class="hljs-value">"10dp"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"Chen Yu"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"23sp"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span> <span class="hljs-tag"><<span class="hljs-title">ListView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/listview"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_below</span>=<span class="hljs-value">"@id/admininfo"</span> <span class="hljs-attribute">android:padding</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">android:divider</span>=<span class="hljs-value">"@null"</span> /></span> <span class="hljs-tag"><<span class="hljs-title">ImageView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/divider"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"2dp"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"?android:attr/listDivider"</span> <span class="hljs-attribute">android:layout_above</span>=<span class="hljs-value">"@+id/qiehuanzhuti"</span> <span class="hljs-attribute">android:layout_alignParentStart</span>=<span class="hljs-value">"true"</span> /></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/qiehuanzhuti"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"切换主题"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"20sp"</span> <span class="hljs-attribute">android:layout_marginLeft</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">android:layout_marginTop</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">android:layout_below</span>=<span class="hljs-value">"@id/listview"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"设置"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"20sp"</span> <span class="hljs-attribute">android:layout_marginLeft</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">android:layout_marginTop</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">android:layout_below</span>=<span class="hljs-value">"@id/qiehuanzhuti"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li></ul>
同时,需要为listview的每一个Item创建一个item view,因此,新建list_item.xml:
<code class="language-xml hljs has-numbering"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag"><<span class="hljs-title">LinearLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"horizontal"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>></span> <span class="hljs-tag"><<span class="hljs-title">ImageView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/actionicon"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"30dp"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"30dp"</span> <span class="hljs-attribute">android:src</span>=<span class="hljs-value">"@mipmap/ic_format"</span> <span class="hljs-attribute">android:layout_margin</span>=<span class="hljs-value">"5dp"</span> /></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/choice"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"选项"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"18sp"</span> <span class="hljs-attribute">android:layout_gravity</span>=<span class="hljs-value">"center_vertical"</span> <span class="hljs-attribute">android:layout_marginLeft</span>=<span class="hljs-value">"15dp"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>
既然有了listView,那么就需要一个适配器,因此我们新建MenuAdapter.java:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MenuAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseAdapter</span> {</span> <span class="hljs-keyword">private</span> LayoutInflater mInflater; <span class="hljs-keyword">private</span> List<String> mData; <span class="hljs-keyword">private</span> List<Integer> mDataIcon; <span class="hljs-keyword">public</span> <span class="hljs-title">MenuAdapter</span>(Context context, List<String> data,List<Integer> dataicon) { <span class="hljs-keyword">this</span>.mInflater = LayoutInflater.from(context); <span class="hljs-keyword">this</span>.mData = data; <span class="hljs-keyword">this</span>.mDataIcon = dataicon; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getCount</span>() { <span class="hljs-keyword">return</span> mData.size(); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> Object <span class="hljs-title">getItem</span>(<span class="hljs-keyword">int</span> position) { <span class="hljs-keyword">return</span> mData.get(position); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">getItemId</span>(<span class="hljs-keyword">int</span> position) { <span class="hljs-keyword">return</span> position; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> View <span class="hljs-title">getView</span>(<span class="hljs-keyword">int</span> position, View convertView, ViewGroup parent) { View view = mInflater.inflate(R.layout.list_item,<span class="hljs-keyword">null</span>); TextView textView = (TextView) view.findViewById(R.id.choice); ImageView imageView = (ImageView) view.findViewById(R.id.actionicon); <span class="hljs-comment">//为每一个item设置一个图标和相应的文字</span> imageView.setImageResource(mDataIcon.get(position)); textView.setText(mData.get(position)); <span class="hljs-keyword">return</span> view; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li></ul>
该adapter继承自BaseAdapter,相信熟悉ListView的都对适配器比较熟悉了,因此这里不再展开来讲了。
Part 3.主页布局
1、实现下拉刷新:SwiperefreshLayout
先新建主页布局文件:content_main.xml,我们看一下上面的图,主页布局主要由如下三者组成:一个toolbar导航栏,一个RecyclerView用于展示数据,以及一个刷新的小圆圈。那么我们的实现思路如下:首先toolbar应该是位于最顶层的,接着利用swiperefreshlayout布局,装载一个RecycleView。代码如下所示:
<code class="language-xml hljs has-numbering"><span class="hljs-tag"><<span class="hljs-title">LinearLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">xmlns:toolbar</span>=<span class="hljs-value">"http://schemas.android.com/apk/res-auto"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span>></span> <span class="hljs-tag"><<span class="hljs-title">android.support.v7.widget.Toolbar </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/toolbar"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"?attr/colorPrimary"</span> <span class="hljs-attribute">toolbar:titleTextColor</span>=<span class="hljs-value">"@android:color/white"</span> <span class="hljs-attribute">toolbar:subtitleTextColor</span>=<span class="hljs-value">"@android:color/white"</span> <span class="hljs-attribute">toolbar:popupTheme</span>=<span class="hljs-value">"@style/ToolbarPopupTheme"</span>></span> <span class="hljs-tag"></<span class="hljs-title">android.support.v7.widget.Toolbar</span>></span> <span class="hljs-tag"><<span class="hljs-title">android.support.v4.widget.SwipeRefreshLayout </span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/swiperefreshlayout"</span>></span> <span class="hljs-tag"><<span class="hljs-title">android.support.v7.widget.RecyclerView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/recyclerview"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> /></span> <span class="hljs-tag"></<span class="hljs-title">android.support.v4.widget.SwipeRefreshLayout</span>></span> <span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul>
关于Toolbar的使用,如果还没用过的可以参考我之前的一篇文章Android ToolBar 使用完全解析,这里就省略了关于Toolbar中的menu的xml文件,可以参考完整的源码。接下来我们看看SwiperefreshLayout这个组件的使用:
这个组件是在v4包里面的,它实际上是一个ViewGroup,但是它内部只能有一个子View,因此,我们可以把RecyclerView放在里面,在布局文件里面的写法很简单,那么我们在Activity内怎么初始化这个控件呢?
与一般控件一样,它都是使用如下方法来获取实例:
<code class="language-java hljs has-numbering">swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefreshlayout);</code><ul style="" class="pre-numbering"><li>1</li></ul>
接着我们看它几个常用的方法:
<code class="language-java hljs has-numbering"> <span class="hljs-comment">//该方法用于指定刷新时进度条的颜色变化,第一个颜色表示进度条出现的初始颜色,这里引用的是资源文件</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setColorSchemeResources</span> (<span class="hljs-keyword">int</span>... colorResIds) /**该方法用于设置刷新监听器,用于监听用户下拉刷新的操作 * 接收的参数是SwipeRefreshLayout.OnRefreshListener,并需要重写该接口的<span class="hljs-title">onRefresh</span>()方法。 * 设置该监听器后,可以使得用户在下拉刷新的时候回调该方法 */ <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setOnRefreshListener</span> (SwipeRefreshLayout.OnRefreshListener listener) //该方法用于设置刷新状态,比如设置为<span class="hljs-keyword">false</span>,那么是停止刷新圆圈的转动 <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setRefreshing</span> (<span class="hljs-keyword">boolean</span> refreshing)</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul>
2、数据内容:CardView
CardView是v7的一个控件,在使用它的时候需要先引入,在build.gradle中修改如下:
<code class="language-xml hljs has-numbering">dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>
这个控件的优点在于,它是一个卡片式的布局,能轻松实现卡片式效果,并且能实现阴影、圆角效果。我们先看它的几个重要的xml属性:
<code class="language-xml hljs has-numbering">app:cardElevation 阴影的大小 app:cardMaxElevation 阴影最大高度 app:cardBackgroundColor 卡片的背景色 app:cardCornerRadius 卡片的圆角大小 app:contentPadding 卡片内容于边距的间隔</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
以上app是自定义的命名空间。通过设置以上的属性,就能配置好一个漂亮的卡片了,接下来为卡片添加各种子View内容,新建item_cardview.xml:
<code class="language-xml hljs has-numbering"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag"><<span class="hljs-title">android.support.v7.widget.CardView </span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">xmlns:app</span>=<span class="hljs-value">"http://schemas.android.com/apk/res-auto"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_margin</span>=<span class="hljs-value">"5dp"</span> <span class="hljs-attribute">app:cardElevation</span>=<span class="hljs-value">"15dp"</span> <span class="hljs-attribute">app:contentPaddingTop</span>=<span class="hljs-value">"2dp"</span> <span class="hljs-attribute">app:contentPaddingBottom</span>=<span class="hljs-value">"4dp"</span>></span> <span class="hljs-tag"><<span class="hljs-title">RelativeLayout </span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span> <span class="hljs-tag"><<span class="hljs-title">RelativeLayout </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/relativelayout"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>></span> <span class="hljs-tag"><<span class="hljs-title">ImageView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/usericon"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"35dp"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"35dp"</span> <span class="hljs-attribute">android:src</span>=<span class="hljs-value">"@mipmap/ic_launcher"</span> <span class="hljs-attribute">android:layout_marginLeft</span>=<span class="hljs-value">"4dp"</span> <span class="hljs-attribute">android:layout_centerVertical</span>=<span class="hljs-value">"true"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/username"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"50dp"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"罗杰斯"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"17sp"</span> <span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"#8cc3ff"</span> <span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center"</span> <span class="hljs-attribute">android:layout_toRightOf</span>=<span class="hljs-value">"@id/usericon"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"50dp"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"赞同了该答案"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"17sp"</span> <span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center_vertical"</span> <span class="hljs-attribute">android:layout_alignParentTop</span>=<span class="hljs-value">"true"</span> <span class="hljs-attribute">android:layout_toRightOf</span>=<span class="hljs-value">"@id/username"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/count"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"50dp"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"25dp"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"1.0k"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"17sp"</span> <span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"#408aff"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#a9d3ff"</span> <span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center"</span> <span class="hljs-attribute">android:layout_centerVertical</span>=<span class="hljs-value">"true"</span> <span class="hljs-attribute">android:layout_alignParentRight</span>=<span class="hljs-value">"true"</span> <span class="hljs-attribute">android:layout_marginRight</span>=<span class="hljs-value">"15dp"</span> /></span> <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/title"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"18sp"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"Android开发测试Demo示例"</span> <span class="hljs-attribute">android:layout_below</span>=<span class="hljs-value">"@id/relativelayout"</span> <span class="hljs-attribute">android:padding</span>=<span class="hljs-value">"4dp"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/content"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:textSize</span>=<span class="hljs-value">"17sp"</span> <span class="hljs-attribute">android:lines</span>=<span class="hljs-value">"3"</span> <span class="hljs-attribute">android:ellipsize</span>=<span class="hljs-value">"end"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容测试内容"</span> <span class="hljs-attribute">android:layout_below</span>=<span class="hljs-value">"@id/title"</span> <span class="hljs-attribute">android:padding</span>=<span class="hljs-value">"4dp"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span> <span class="hljs-tag"></<span class="hljs-title">android.support.v7.widget.CardView</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li></ul>
3、数据列表:RecyclerView
接着,我们继续完善主页,我们需要一个数据呈现的控件,RecyclerView,该控件的详细使用方法可以参考我的一篇文章:揭开RecyclerView的神秘面纱(一):RecyclerView的基本使用,上面所说的CardView正是这里RecyclerView的一个子Item view,我们新建一个MyAdapter.java,即RecyclerView的数据适配器:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">Adapter</span><<span class="hljs-title">MyAdapter</span>.<span class="hljs-title">MyViewHolder</span>> {</span> <span class="hljs-keyword">private</span> List<MessageObj> mData; <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> MyViewHolder <span class="hljs-title">onCreateViewHolder</span>(ViewGroup viewGroup, <span class="hljs-keyword">int</span> i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_cardview,viewGroup,<span class="hljs-keyword">false</span>); MyViewHolder vh = <span class="hljs-keyword">new</span> MyViewHolder(v); <span class="hljs-keyword">return</span> vh; } <span class="hljs-keyword">public</span> <span class="hljs-title">MyAdapter</span>(List<MessageObj> data){ mData = data; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span>(MyViewHolder myViewHolder, <span class="hljs-keyword">int</span> i) { myViewHolder.mUsername.setText(mData.get(i).getUsername()); myViewHolder.mUserIcon.setImageResource(mData.get(i).getIcon()); myViewHolder.mCount.setText(mData.get(i).getCount()); myViewHolder.mTitle.setText(mData.get(i).getTitle()); myViewHolder.mContent.setText(mData.get(i).getContent()); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemCount</span>() { <span class="hljs-keyword">return</span> mData.size(); } <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyViewHolder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span> {</span> <span class="hljs-keyword">public</span> TextView mUsername; <span class="hljs-keyword">public</span> TextView mCount; <span class="hljs-keyword">public</span> TextView mTitle; <span class="hljs-keyword">public</span> TextView mContent; <span class="hljs-keyword">public</span> ImageView mUserIcon; <span class="hljs-keyword">public</span> <span class="hljs-title">MyViewHolder</span>(View itemView) { <span class="hljs-keyword">super</span>(itemView); mUsername = (TextView) itemView.findViewById(R.id.username); mUserIcon = (ImageView) itemView.findViewById(R.id.usericon); mCount = (TextView) itemView.findViewById(R.id.count); mTitle = (TextView) itemView.findViewById(R.id.title); mContent = (TextView) itemView.findViewById(R.id.content); } } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li></ul>
接着,我们要写一个消息实体类,因为每一个ItemView的内容都是通过网络加载或者本地缓存都获得的,因此,我们新建MessageObj.java:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MessageObj</span> {</span> <span class="hljs-keyword">private</span> String username; <span class="hljs-keyword">private</span> String count; <span class="hljs-keyword">private</span> String title; <span class="hljs-keyword">private</span> String content; <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> icon; <span class="hljs-keyword">public</span> <span class="hljs-title">MessageObj</span>(String username,<span class="hljs-keyword">int</span> icon ,String count, String title, String content) { <span class="hljs-keyword">this</span>.username = username; <span class="hljs-keyword">this</span>.count = count; <span class="hljs-keyword">this</span>.title = title; <span class="hljs-keyword">this</span>.content = content; <span class="hljs-keyword">this</span>.icon = icon; } <span class="hljs-keyword">public</span> String <span class="hljs-title">getUsername</span>() { <span class="hljs-keyword">return</span> username; } <span class="hljs-keyword">public</span> String <span class="hljs-title">getContent</span>() { <span class="hljs-keyword">return</span> content; } <span class="hljs-keyword">public</span> String <span class="hljs-title">getTitle</span>() { <span class="hljs-keyword">return</span> title; } <span class="hljs-keyword">public</span> String <span class="hljs-title">getCount</span>() { <span class="hljs-keyword">return</span> count; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getIcon</span>() { <span class="hljs-keyword">return</span> icon; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li></ul>
到目前为止,通过使用RecyclerView+CardView实现了数据列表的呈现,通过SwiperefreshLayout实现了下拉刷新的功能,通过Toolbar实现了导航的功能,通过DrawerLayout实现了侧滑菜单的功能。那么最后,我们需要在Activity中,对以上一系列控件初始化以及准备数据的提供。
Part 4.MainActivity
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span> <span class="hljs-keyword">private</span> RecyclerView recyclerView; <span class="hljs-keyword">private</span> SwipeRefreshLayout swipeRefreshLayout; <span class="hljs-keyword">private</span> DrawerLayout drawerLayout; <span class="hljs-keyword">private</span> ActionBarDrawerToggle actionBarDrawerToggle; <span class="hljs-keyword">private</span> ListView listView; <span class="hljs-keyword">private</span> List<MessageObj> mData; <span class="hljs-keyword">private</span> Toolbar toolbar; <span class="hljs-keyword">private</span> List<String> choices; <span class="hljs-keyword">private</span> List<Integer> choiceIcon; <span class="hljs-keyword">private</span> MyAdapter recyclerAdapter; <span class="hljs-keyword">private</span> Handler mHandler = <span class="hljs-keyword">new</span> Handler(){ <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleMessage</span>(Message msg) { <span class="hljs-keyword">super</span>.handleMessage(msg); <span class="hljs-keyword">switch</span> (msg.what){ <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>: swipeRefreshLayout.setRefreshing(<span class="hljs-keyword">false</span>); recyclerAdapter.notifyDataSetChanged(); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">default</span>: <span class="hljs-keyword">break</span>; } } }; <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initViews(); } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initViews</span>() { <span class="hljs-javadoc">/** * 初始化Toolbar */</span> toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle(<span class="hljs-string">"首页"</span>); <span class="hljs-comment">//设置导航图标、添加菜单点击事件要在setSupportActionBar方法之后</span> setSupportActionBar(toolbar); toolbar.setNavigationIcon(R.mipmap.ic_drawer_home); toolbar.setOnMenuItemClickListener(<span class="hljs-keyword">new</span> Toolbar.OnMenuItemClickListener() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onMenuItemClick</span>(MenuItem item) { <span class="hljs-keyword">switch</span> (item.getItemId()) { <span class="hljs-keyword">case</span> R.id.action_search: Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"Search !"</span>, Toast.LENGTH_LONG).show(); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">case</span> R.id.action_notifications: Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"Notification !"</span>, Toast.LENGTH_LONG).show(); <span class="hljs-keyword">break</span>; } <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } }); <span class="hljs-javadoc">/** * 初始化RecyclerView */</span> recyclerView = (RecyclerView) findViewById(R.id.recyclerview); recyclerView.setLayoutManager(<span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>)); recyclerAdapter = <span class="hljs-keyword">new</span> MyAdapter(mData); recyclerView.setAdapter(recyclerAdapter); <span class="hljs-javadoc">/** * 初始化swipeRefreshLayout */</span> swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefreshlayout); swipeRefreshLayout.setColorSchemeResources(R.color.color_blue); swipeRefreshLayout.setOnRefreshListener(<span class="hljs-keyword">new</span> SwipeRefreshLayout.OnRefreshListener() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onRefresh</span>() { <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> Runnable() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() { Collections.reverse(mData); <span class="hljs-keyword">try</span> { Thread.sleep(<span class="hljs-number">1000</span>); <span class="hljs-comment">//模拟耗时操作</span> } <span class="hljs-keyword">catch</span> (InterruptedException e) { e.printStackTrace(); } mHandler.sendEmptyMessage(<span class="hljs-number">1</span>); } }).start(); } }); <span class="hljs-javadoc">/** * 初始化侧滑菜单 DrawerLayout */</span> drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); actionBarDrawerToggle = <span class="hljs-keyword">new</span> ActionBarDrawerToggle( <span class="hljs-keyword">this</span>, drawerLayout,toolbar,R.string.drawer_open,R.string.drawer_close ); drawerLayout.setDrawerListener(actionBarDrawerToggle); listView = (ListView) findViewById(R.id.listview); ListAdapter adapter = <span class="hljs-keyword">new</span> MenuAdapter(<span class="hljs-keyword">this</span>,choices,choiceIcon); listView.setAdapter(adapter); } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initData</span>() { mData = <span class="hljs-keyword">new</span> ArrayList<MessageObj>(); MessageObj obj1 = <span class="hljs-keyword">new</span> MessageObj(<span class="hljs-string">"神盾局"</span>,R.mipmap.shield,<span class="hljs-string">"5.6K"</span>,<span class="hljs-string">"神盾局是怎么样的一个组织?"</span>, <span class="hljs-string">"神盾局,全称为国土战略防御攻击与后勤保障局,由斯坦·李与杰克·科比联合创造。神盾局是国际安全理事会专门用于处理各种奇异事件的特殊部队"</span>); mData.add(obj1); MessageObj obj2 = <span class="hljs-keyword">new</span> MessageObj(<span class="hljs-string">"Stark"</span>,R.mipmap.stark,<span class="hljs-string">"7.8K"</span>,<span class="hljs-string">"钢铁侠是谁?"</span>, <span class="hljs-string">"托尼·斯塔克(小罗伯特·唐尼饰)是“斯塔克工业”的董事长,作为钢铁侠 官方剧照钢铁侠军火商他毁誉不一,但还是过着上流生活。此时,"</span>); mData.add(obj2); MessageObj obj3 = <span class="hljs-keyword">new</span> MessageObj(<span class="hljs-string">"索尔"</span>,R.mipmap.thor,<span class="hljs-string">"7.8K"</span>,<span class="hljs-string">"雷神索尔的能力如何?"</span>, <span class="hljs-string">"北欧神话里挥舞着大铁锤、掌控着风暴和闪电的天神,还能用铁锤打开时空之门。暴脾气的他因为自大鲁莽的行为重新点燃了一场古老战争的战火,之后被贬到凡间被迫与人类一起生活。"</span>); mData.add(obj3); MessageObj obj4 = <span class="hljs-keyword">new</span> MessageObj(<span class="hljs-string">"罗杰斯"</span>,R.mipmap.steven,<span class="hljs-string">"7.8K"</span>,<span class="hljs-string">"怎么评价美国队长3?"</span>, <span class="hljs-string">"该片根据漫威2006年出版的漫画大事件《内战》改编,背景故事承接于《复仇者联盟2:奥创纪元》事件的余波中,讲述了奥创事件后引发的"</span>); mData.add(obj4); MessageObj obj5 = <span class="hljs-keyword">new</span> MessageObj(<span class="hljs-string">"黑寡妇"</span>,R.mipmap.widow,<span class="hljs-string">"7.8K"</span>,<span class="hljs-string">"黑寡妇是一个怎么样的角色?"</span>, <span class="hljs-string">"1928年出生于前苏联的斯大林格勒,自幼被前苏联特工人员训练成特工,身体经前苏联政府基因改造后大大延缓了其衰老速度,并增强其免疫系统以及抗击打能力,加上本身多年的各种体能及精神上的训练"</span>); mData.add(obj5); choices = <span class="hljs-keyword">new</span> ArrayList<String>(); choiceIcon = <span class="hljs-keyword">new</span> ArrayList<>(); choices.add(<span class="hljs-string">"首页"</span>); choices.add(<span class="hljs-string">"发现"</span>); choices.add(<span class="hljs-string">"关注"</span>); choices.add(<span class="hljs-string">"收藏"</span>); choices.add(<span class="hljs-string">"圆桌"</span>); choices.add(<span class="hljs-string">"私信"</span>); choiceIcon.add(R.mipmap.ic_main); choiceIcon.add(R.mipmap.ic_find); choiceIcon.add(R.mipmap.ic_attention); choiceIcon.add(R.mipmap.ic_collect); choiceIcon.add(R.mipmap.ic_circle); choiceIcon.add(R.mipmap.ic_message); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onCreateOptionsMenu</span>(Menu menu) { <span class="hljs-comment">// Inflate the menu; this adds items to the action bar if it is present.</span> getMenuInflater().inflate(R.menu.menu_main, menu); <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li></ul>
最后,可以运行一下,就会发现结果和一开始的效果是一样的了。