转自:http://blog.csdn.net/ygl_smile/article/details/52094120
RecyclerView 初识
RecyclerView 是Android 5.0 materials design中的组件之一,其目标是替代广为使用的ListView.其有什么特点呢?从名字就可以看出个大概来 recycler(反复循环器),也就是RecyclerView 只负责子视图的回收和复用其他的统统交给用户,因此相较于ListView 其更加灵活可以定制更多的个性也更符合我们低耦合的编程思想。
RecyclerView的功能甚是强大,虽然较ListView 实现起来略微复杂但怎么艺术般的控件绝对值得你我一试。
准备工作
RecyclerView 放在 android-support-v7.jar 中,如果本地v7包中没有可以用sdkManager下载/更新Android Support Libraries(目前最新版本为 21)。如果被困在墙内无法更新,可以从网盘直接下载,加入到项目libs中。
网盘地址:http://pan.baidu.com/s/1nuFYBRb
做个对比
ListView 我们已经比较熟悉,使用也较为简单
<code class="language-java hljs has-numbering"><span class="hljs-comment">//设置适配器</span> listView.setAdapter(<span class="hljs-keyword">new</span> MyAdapter(mContext));</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
RecyclerView 则需要较多的步骤
<code class="language-java hljs has-numbering"><span class="hljs-comment">//设置适配器</span> mRecyclerView.setAdapter(<span class="hljs-keyword">new</span> MyAdapter(mContext)); <span class="hljs-comment">//设置布局样式</span> mRecyclerView.setLayoutManager(<span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>)); <span class="hljs-comment">//设置分割线</span> mRecyclerView.addItemDecoration(<span class="hljs-keyword">new</span> LinearItemDecoration(<span class="hljs-keyword">this</span>, R.drawable.main_recycler_divider)); <span class="hljs-comment">//设置默认的Item动画</span> mRecyclerView.setItemAnimator(<span class="hljs-keyword">new</span> DefaultItemAnimator());</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></ul>
对照以上,本文将从以下几点详细介绍RecyclerView 的使用:
- 继承RecyclerView.Adapter 实现自己的适配器
- RecyclerView.LayoutManager抽象类的介绍
- 实现RecyclerView.ItemDecoration抽象类绘制个性分割线
- 好看的Item添加,删除动画
实现自己的适配器:
该部分并没有什么难点,不做过多解释
<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">MainAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">Adapter</span><<span class="hljs-title">MainAdapter</span>.<span class="hljs-title">ViewHolder</span>>{</span> <span class="hljs-keyword">private</span> LayoutInflater layoutInflater; <span class="hljs-keyword">private</span> ArrayList<ItemObj> datas; <span class="hljs-keyword">private</span> Context context; <span class="hljs-keyword">public</span> <span class="hljs-title">MainAdapter</span>(Context context){ <span class="hljs-keyword">this</span>.context = context; <span class="hljs-keyword">this</span>.layoutInflater = LayoutInflater.from(context); <span class="hljs-keyword">this</span>.datas = <span class="hljs-keyword">new</span> ArrayList<>(); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>;i<<span class="hljs-number">15</span>;i++){ <span class="hljs-comment">//通过getIdentifier获得资源id的时候文件名不要带后缀</span> <span class="hljs-keyword">int</span> imgId = context.getResources().getIdentifier(<span class="hljs-string">"img_"</span>+(i+<span class="hljs-number">1</span>), <span class="hljs-string">"drawable"</span>, <span class="hljs-string">"com.ygl.road"</span>); ItemObj item = <span class="hljs-keyword">new</span> ItemObj(String.valueOf(i+<span class="hljs-number">1</span>), imgId); datas.add(item); } } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> ViewHolder <span class="hljs-title">onCreateViewHolder</span>(ViewGroup viewGroup, <span class="hljs-keyword">int</span> i) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ViewHolder(layoutInflater.inflate(R.layout.main_recycler_item_layout, viewGroup, <span class="hljs-keyword">false</span>)); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span>(ViewHolder viewHolder, <span class="hljs-keyword">int</span> i) { viewHolder.textView.setText(datas.get(i).getText()); viewHolder.imageView.setImageDrawable(ContextCompat.getDrawable(context, datas.get(i).getDrawableId())); } <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> datas.size(); } <span class="hljs-comment">/*当Item有多种类型的时候,通过此方法返回Item的类型*/</span> <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemViewType</span>(<span class="hljs-keyword">int</span> position) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">super</span>.getItemViewType(position); } <span class="hljs-keyword">final</span> class ViewHolder extends RecyclerView.ViewHolder{ TextView textView; ImageView imageView; <span class="hljs-keyword">public</span> <span class="hljs-title">ViewHolder</span>(View itemView) { <span class="hljs-keyword">super</span>(itemView); textView = (TextView) itemView.findViewById(R.id.main_recycler_item_text); imageView = (ImageView) itemView.findViewById(R.id.main_recycler_item_image); } } }</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></ul>
LayoutManager快速的实现不同的布局样式:
RecyclerView.LayoutManager 是一个抽象类,喜欢研究源码的童鞋可以查看一下源码,这个类主要是对item的大小和位置属性进行了计算,代码较为复杂。好在的是google给我们提供了三个实现类。
<code class="language-java hljs has-numbering"><span class="hljs-comment">/*横竖显示,竖列显示时与ListView相似 *context上下文 |item排列方向 | 是否倒序显示*/</span> LinearLayoutManager llm = <span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>, LinearLayoutManager.HORIZONTAL, <span class="hljs-keyword">false</span>); <span class="hljs-comment">/*以表格的形式显示,与GridView相似 *context上下文 | 每行/列item个数 | item排列方向 | 是否倒序显示*/</span> GridLayoutManager glm = <span class="hljs-keyword">new</span> GridLayoutManager(<span class="hljs-keyword">this</span>, <span class="hljs-number">2</span>, GridLayoutManager.VERTICAL, <span class="hljs-keyword">false</span>); <span class="hljs-comment">/*通过设置item 的LayoutParams值可以实现瀑布样式的布局 *每行/列item个数 | item排列方向*/</span> StaggeredGridLayoutManager sglm = <span class="hljs-keyword">new</span> StaggeredGridLayoutManager(<span class="hljs-number">2</span>, StaggeredGridLayoutManager.VERTICAL);</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>
RecyclerView通过setLayoutManager(LayoutManger)设置布局管理;
当使用普通的LinearLayoutManager时:
<code class="hljs cs has-numbering">LinearLayoutManager llm = <span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>, LinearLayoutManager.HORIZONTAL, <span class="hljs-keyword">false</span>); mRecyclerView.setLayoutManager(llm);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
LinearLayoutManager
或许会感觉这很普通啊,ListView 实现起来分分钟钟的事,还搞的这么麻烦,不划算啊!!!
咱程序员可从不是舍近求远的人,来个大招瞅瞅!!!
只需要更改一行代码, 一秒钟变GridView
<code class="hljs cs has-numbering">GridLayoutManager glm = <span class="hljs-keyword">new</span> GridLayoutManager(<span class="hljs-keyword">this</span>, <span class="hljs-number">2</span>, GridLayoutManager.VERTICAL, <span class="hljs-keyword">false</span>); mRecyclerView.setLayoutManager(glm);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
GridLayoutManager
如果感觉还是一般的话,可以试试改变LayoutManager的排列方向,立马让你横着滑。对于有竖屏竖着滑横屏横着滑的童鞋,RecyclerView 简直就是神器啊!!
ItemDecoration绘制个性分割线:
用过ListView的童鞋都知道,在ListView中我们可以通过setDivider()简单粗暴的实现分割线,在为RecyclerView设置分割线的时候你会发现傲娇如他是不会让你就这么随随便便的设置的了。
RecyclerView的内部抽象类ItemDecoration是我们实现分割线的关键。设置分割线大概思路是:根据ItemView的大小及dividerDrawable的宽,高,计算divider的宽高和ItemView的偏移值。细心的童鞋就会发现,绘制divider的时候其实是跟具体的Item内容是没有关系的。因此我们可以编写一个低耦合的divider计算类以便在以后可以方便的使用。
BaseItemDecoration是自定义的抽象类,他继承自RecyclerView.ItemDecoration,在其中实现一些公用方法
<code class="hljs java has-numbering"><span class="hljs-javadoc">/** * Created by Ygl on 2016/8/1. * 绘制 RecyclerView 的分割线 * * onDraw 优先于 drawChildren * onDrawOver 在 drawChildren 之后,一般重写其中一个即可 * getItemOffsets 可以通过 outRect.set() 为每一个Item设置一定的偏移量 */</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseItemDecoration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ItemDecoration</span>{</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> HORIZONTAL = LinearLayoutManager.HORIZONTAL; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> VERTICAL = LinearLayoutManager.VERTICAL; <span class="hljs-keyword">protected</span> Drawable mDivider;<span class="hljs-comment">//分割线</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">int</span> orientation;<span class="hljs-comment">//排列方向</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">boolean</span> isLastDraw;<span class="hljs-comment">//是否绘制最后的边线</span> <span class="hljs-keyword">public</span> <span class="hljs-title">BaseItemDecoration</span>(Context context, <span class="hljs-keyword">int</span> drawableId){ <span class="hljs-keyword">this</span>(context, drawableId, VERTICAL); } <span class="hljs-keyword">public</span> <span class="hljs-title">BaseItemDecoration</span>(Context context, <span class="hljs-keyword">int</span> drawableId, <span class="hljs-keyword">int</span> orientation){ <span class="hljs-keyword">if</span>(orientation != HORIZONTAL && orientation != VERTICAL){ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"invalid orientation,you can choose 'HORIZONTAL_LIST' or 'VERTICAL_LIST'"</span>); } <span class="hljs-keyword">this</span>.orientation = orientation; <span class="hljs-keyword">this</span>.mDivider = ContextCompat.getDrawable(context, drawableId); <span class="hljs-keyword">this</span>.isLastDraw = <span class="hljs-keyword">true</span>; } <span class="hljs-javadoc">/** * 是否绘制最后的边线 *<span class="hljs-javadoctag"> @param</span> isLastDraw */</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">isLastDraw</span>(<span class="hljs-keyword">boolean</span> isLastDraw){ <span class="hljs-keyword">this</span>.isLastDraw = isLastDraw; } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawDivider</span>(<span class="hljs-keyword">int</span> left, <span class="hljs-keyword">int</span> top,<span class="hljs-keyword">int</span> right,<span class="hljs-keyword">int</span> bottom, Canvas c){ mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawHorizontal</span>(Canvas c, RecyclerView parent); <span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawVertical</span>(Canvas c, RecyclerView parent); }</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></ul>
接下来实现一个具体的分割线类 LinearItemDecoration,在采用ListView的样式时就可以直接拿来用了。这段代码的重点是计算一下要绘制的分割线的宽度和高度。如果只是看着不好懂得话,小伙伴们可以拿出笔和纸画一画还是很好理解的。代码有点长,不过有了上一个的经验这个还是很好理解的。其与上一个的主要区别在于,上一个只需要绘制一边,而在网格中则需要绘制底边和右边。
<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinearItemDecoration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseItemDecoration</span>{</span> <span class="hljs-keyword">public</span> <span class="hljs-title">LinearItemDecoration</span>(Context context, <span class="hljs-keyword">int</span> dividerId){ <span class="hljs-keyword">super</span>(context, dividerId); } <span class="hljs-keyword">public</span> <span class="hljs-title">LinearItemDecoration</span>(Context context, <span class="hljs-keyword">int</span> dividerId, <span class="hljs-keyword">int</span> orientation){ <span class="hljs-keyword">super</span>(context, dividerId, orientation); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDraw</span>(Canvas c, RecyclerView parent, RecyclerView.State state) { <span class="hljs-keyword">super</span>.onDraw(c, parent, state); <span class="hljs-keyword">if</span>(orientation == HORIZONTAL){ drawHorizontal(c, parent); }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(orientation == VERTICAL){ drawVertical(c, parent); } } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getItemOffsets</span>(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { <span class="hljs-comment">/*横向排列时,将childView 的 rightPadding 加上 divider的宽度 如果不加,分割线视图会被覆盖*/</span> <span class="hljs-keyword">if</span>(orientation == HORIZONTAL){ outRect.set(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, mDivider.getIntrinsicWidth(), <span class="hljs-number">0</span>); }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(orientation == VERTICAL){ outRect.set(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, mDivider.getIntrinsicHeight()); } } <span class="hljs-comment">/*若采用纵向的排列方式*/</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawVertical</span>(Canvas c, RecyclerView parent){ <span class="hljs-keyword">if</span>(c == <span class="hljs-keyword">null</span> || parent == <span class="hljs-keyword">null</span>){ <span class="hljs-keyword">return</span>; } <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> left = parent.getPaddingLeft(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> right = parent.getWidth()-parent.getPaddingRight(); <span class="hljs-keyword">int</span> childCount = parent.getChildCount(); <span class="hljs-keyword">if</span>(!isLastDraw)childCount--; <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>;i<childCount;i++){ <span class="hljs-keyword">final</span> View child = parent.getChildAt(i); <span class="hljs-keyword">final</span> RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> top = child.getBottom() + params.bottomMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> bottom = top + mDivider.getIntrinsicHeight(); drawDivider(left, top, right, bottom, c); } } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawHorizontal</span>(Canvas c, RecyclerView parent){ <span class="hljs-keyword">if</span>(c== <span class="hljs-keyword">null</span> || parent == <span class="hljs-keyword">null</span>)<span class="hljs-keyword">return</span>; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> top = parent.getPaddingTop(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> bottom = parent.getHeight()-parent.getPaddingBottom(); <span class="hljs-keyword">int</span> childCount = parent.getChildCount(); <span class="hljs-keyword">if</span>(!isLastDraw)childCount--; <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>;i<childCount;i++){ <span class="hljs-keyword">final</span> View childView = parent.getChildAt(i); <span class="hljs-keyword">final</span> RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> left = childView.getRight()+params.rightMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> right = left+mDivider.getIntrinsicWidth(); drawDivider(left, top, right, bottom, c); } } }</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>
RecyclerView 的功能可不仅仅是实现一个ListView样式那么简单啊!!网格,瀑布什么的显然我们上边实现的这个divider不是很适用,我们再来写一个用于网格的divider.
<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GridItemDecoration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseItemDecoration</span> {</span> <span class="hljs-keyword">public</span> <span class="hljs-title">GridItemDecoration</span>(Context context, <span class="hljs-keyword">int</span> dividerId) { <span class="hljs-keyword">super</span>(context, dividerId); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDraw</span>(Canvas c, RecyclerView parent, RecyclerView.State state) { drawHorizontal(c, parent); drawVertical(c, parent); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getItemOffsets</span>(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { <span class="hljs-keyword">int</span> spanCount = getSpanCount(parent); <span class="hljs-keyword">int</span> childCount = parent.getAdapter().getItemCount(); <span class="hljs-keyword">if</span>(isLastRaw(parent, ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewPosition(), spanCount, childCount)){ outRect.set(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, mDivider.getIntrinsicWidth(), <span class="hljs-number">0</span>); }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(isLastColum(parent, ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewPosition(), spanCount, childCount)){ outRect.set(<span class="hljs-number">0</span> ,<span class="hljs-number">0</span> ,<span class="hljs-number">0</span>, mDivider.getIntrinsicHeight()); }<span class="hljs-keyword">else</span>{ outRect.set(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); } } <span class="hljs-comment">//获得列数</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getSpanCount</span>(RecyclerView parent){ RecyclerView.LayoutManager manager = parent.getLayoutManager(); <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> GridLayoutManager){ <span class="hljs-keyword">return</span> ((GridLayoutManager)manager).getSpanCount(); }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> StaggeredGridLayoutManager){ <span class="hljs-keyword">return</span> ((StaggeredGridLayoutManager)manager).getSpanCount(); } <span class="hljs-keyword">return</span> -<span class="hljs-number">1</span>; } <span class="hljs-comment">//是否为最后一列,最后一列不需要绘制右边</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isLastColum</span>(RecyclerView parent, <span class="hljs-keyword">int</span> pos, <span class="hljs-keyword">int</span> spanCount, <span class="hljs-keyword">int</span> childCount){ RecyclerView.LayoutManager manager = parent.getLayoutManager(); <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> GridLayoutManager){ <span class="hljs-keyword">if</span>((pos+<span class="hljs-number">1</span>)%spanCount == <span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> StaggeredGridLayoutManager){ <span class="hljs-keyword">int</span> orientation = ((StaggeredGridLayoutManager)manager).getOrientation(); <span class="hljs-keyword">if</span>(orientation == StaggeredGridLayoutManager.VERTICAL){ <span class="hljs-keyword">if</span>((pos+<span class="hljs-number">1</span>)%spanCount == <span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; }<span class="hljs-keyword">else</span> { childCount = childCount - childCount%spanCount; <span class="hljs-keyword">if</span>(pos > childCount)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } } <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; } <span class="hljs-comment">//是否为最后一行,最后一行不需要绘制底边</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isLastRaw</span>(RecyclerView parent, <span class="hljs-keyword">int</span> pos, <span class="hljs-keyword">int</span> spanCount, <span class="hljs-keyword">int</span> childCount){ RecyclerView.LayoutManager manager = parent.getLayoutManager(); <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> GridLayoutManager){ childCount = childCount - childCount%spanCount; <span class="hljs-keyword">if</span>(pos > childCount)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(manager <span class="hljs-keyword">instanceof</span> StaggeredGridLayoutManager){ <span class="hljs-keyword">int</span> orientation = ((StaggeredGridLayoutManager)manager).getOrientation(); <span class="hljs-keyword">if</span>(orientation == StaggeredGridLayoutManager.VERTICAL){ childCount = childCount - childCount%spanCount; <span class="hljs-keyword">if</span>(pos > childCount)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; }<span class="hljs-keyword">else</span>{ <span class="hljs-keyword">if</span>((pos+<span class="hljs-number">1</span>) % spanCount == <span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } } <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawHorizontal</span>(Canvas c,RecyclerView parent){ <span class="hljs-keyword">int</span> childCount = parent.getChildCount(); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>;i<childCount;i++){ <span class="hljs-keyword">final</span> View child = parent.getChildAt(i); <span class="hljs-keyword">final</span> RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> left = child.getLeft() - params.leftMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> right = child.getRight()+params.rightMargin+mDivider.getIntrinsicWidth(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> top = child.getBottom()+params.bottomMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> bottom = top+mDivider.getIntrinsicHeight(); drawDivider(left, top, right, bottom, c); } } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawVertical</span>(Canvas c, RecyclerView parent){ <span class="hljs-keyword">int</span> childCount = parent.getChildCount(); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>;i<childCount;i++){ <span class="hljs-keyword">final</span> View child = parent.getChildAt(i); <span class="hljs-keyword">final</span> RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> left = child.getRight()+params.rightMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> right = left+mDivider.getIntrinsicWidth(); <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> top = child.getTop()-params.topMargin; <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> bottom = child.getBottom()+params.bottomMargin; drawDivider(left, top, right, bottom, c); } } }</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></ul>
怎么能少得了动画呢?
在RecyclerView 中可以设置Item的添加,移除动画,通过设置 ItemAnimator。ItemAnimator 是一个抽象类,不过不用担心,google已经为我们实现了一个默认ItemAnimator 效果还是很不错的基本可以满足平时编程的需求,而且在github上还有许多关于ItemAnimation的项目,感兴趣的童鞋可以搜搜看看。
通过以下代码就可以设置默认动画了。
<code class="hljs cs has-numbering">mRecyclerView.setItemAnimator(<span class="hljs-keyword">new</span> DefaultItemAnimator());</code><ul style="" class="pre-numbering"><li>1</li></ul>
结束语
需要源码的童鞋可以在git上下载:https://git.coding.net/ygl12337/android_road.git
首次写博客肯定有很多不足的地方,望有缘看到的网友多多指出,多多支持。