关闭

【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(二)——大图显示模式、评论“盖楼”效果实现详解

927人阅读 评论(0) 收藏 举报
分类:

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

在前一篇文章中,我们学习了如何进行逆向工程和TcpDump进行抓包,获取我们的数据接口,那么有了数据之后,我们就可以开始代码编写工作了。 
本项目在前几天获得了daimajia大神的推荐,star数已经达到115,多谢大家的支持,欢迎提建议和意见。 
项目地址:https://github.com/ZhaoKaiQiang/JianDan

目前项目已完成以下功能,本文章将会总结在编码过程中遇到的挑战和解决方案。

项目进度

已完成的功能

  • 查看段子
  • 查看无聊图(静态图和GIF动态图)
  • 查看妹子图(程序员必备)
  • 对段子、无聊图、妹子图进行投票
  • 段子的复制与分享
  • 无聊图、妹子图的保存与分享
  • 查看吐槽与回复
  • 图片详情页的动画效果
  • 添加新鲜事列表页
  • 添加新鲜事详情页

优化的功能

  • 添加加载等待动画
  • 添加加载失败提示
  • 添加段子列表界面,点击标题栏快速返回顶端
  • 添加评论楼层过多隐藏
  • 添加网络状态检测
  • 优化无聊图列表显示,非WIFI状态下,显示GIF缩略图,点击后下载
  • 加载模式全自动智能切换,显著提高加载速度,节省大量流量
  • 修改图片详情页为完全沉浸效果
  • 图片详情页添加投票结果的颜色标示
  • 添加图片列表滚动检测,滚动状态暂停加载,进一步提高加载速度,减少卡顿
  • 添加图片加载图片
  • 添加当前栏目标志,避免重复切换
  • 修改新鲜事列表页效果为CardView

想完成但没有完成的功能

  • 列表加载动画(虽然试过好多次,但是都不能实现首次加载,CardView进入时的动画效果,如果你能知道我如何实现,我将非常感激)
  • 本地缓存(后期将添加)

效果图

 
 

项目整体架构介绍

使用的开源框架

项目整体介绍

从上面的效果图也可以看出来,我们使用的是Material Design风格,但是并不纯正,为了兼容4.x版本,我们使用Theme.AppCampat兼容主题、RecycleView和CardView来完成,从整体视觉效果来看比较统一和美观。同时为了整体的效果,使用开源项目material-dialogs来实现Material Design效果的对话框,这个在点击回复,完善个人信息的功能点上有所体现。

除了界面,网络请求框架我选择的是Volley,原因是Volley对小数据量、请求频繁的网络操作进行了优化,对于这个项目比较合适,而且作为Google的推荐项目,现在已经完善的比较成熟了,经过了很多项目的实战验证,所以比较放心。而且扩展性非常强,可以定制我们自己的请求解析需求,这一点相信看过我项目的朋友,应该有所感受,在com.socks.jiandan.net包下的请求类都经过了我的定制,使用方便。而且很重要的一点是,Volley在2.3之后是基于HttpURLConnection的封装实现,默认支持gzip压缩,在4.0之后的版本,还支持结果缓存,所以在性能和数据传输量上,相比HttpClient有很大的提高。

在本项目中一个很重要的功能就是加载图片,所以在图片加载框架上需要特别注意。最初我选择的图片加载框架是Fresco,因为之前翻译过关于Fresco的特性的文章,感觉非常的强大,所以想试一试。但是在后面使用的时候,还是遇到了很多的问题,让我不得不暂时放弃Fresco,改用UIL。原因如下:

  • 推出时间太短,虽然功能强大,但是还没经过考验,还不很成熟。Fresco的更新频率很快,我开始用的时候还是0.1.0版本,后来在加载图片的时候遇到问题,在这个版本上,Fresco没有对有304缓存的图片进行处理,所以在加载这类图片的时候会出现失败,我给Fresco项目提交issue之后,他们回复我,Fresco已经升级,在0.2.0完成了问题修复。所以我觉得,Fresco还需要一段时间的考验和完善,才能被用到生产环境中,现在我不很推荐大家在项目中使用
  • 不支持wrap_content。放弃Fresco的一个很重要的原因就是因为它不支持wrap_content,Fresco只支持match和固定长宽,在这个项目中需要展示大量宽度match,高度不定的图片,因为Fresco显示图片的控件也是自己定制的,所以自定义控件这条路也比较难走,在没有找到更好的解决方案的情况下,我决定暂时放弃Fresco,改用UIL。在本项目中,只有在评论列表页的头像是使用的Fresco,其他地方都是使用UIL和自定义控件实现,具体实现方案我会在下面讲到。

在IOC框架的选择上,使用butter knife,之前一直使用AFinal,但是AFinal属于运行期绑定,会影响性能,butter knife属于编译期绑定,不会影响。使用butter knife使用非常方便,就拿来一用。在本项目中,我感觉其实并不是很需要IOC,仅作一个尝试而已,不必深究。

在完成网络状态切换的功能上,需要在MainActivity注册一个网络状态监听器,当网络状态发生改变的时候,通知当前显示的Fragment切换图片的加载模式,或者是提示网络状态变化情况。在这种需求下,使用接口是可以完成的,每个Fragment都实现MainActivity的一个接口,当网络状态发生变化的时候,MainActivity调用Fragment的接口方法即可。但是这样不仅很麻烦,而且会增加耦合性,为此,我使用EventBus完成了这个功能,实现很简单,大家看源码就可以,耦合度为0。

这个项目中的所有数据接口基本都是Json格式,所以选择一个好的解析框架是很重要的。我之前写过三篇文章介绍了Json的不同解析方法,虽然Jackson的解析速度快,但是gson确实用起来很熟悉,而且我们要解析的数据量并不大,性能上的差异微乎其微,所以我选择了我比较熟悉的gson。在解析的一些地方还用到了一些JSON,这个大家可以自由选择。

项目中遇到的问题及解决方案

加载任意高度的图片

我们在前面介绍Fresco的时候提到过,之所以放弃它,很大的一个原因就是因为这个功能它不支持,我们先来看看我们要实现功能的详细分析。

  • 图片宽度要和ImageView的相同
  • 在上一个条件满足的情况下,完整的显示这个图片,高度自适应

也就是下面的效果

我的解决思路是这样的,宽度和ImageView相同,那么设置为match_parent即可,高度则是wrap_content,但是这样显示之后,图片可以完整显示,但是不能符合我们宽度填充,高度自适应的要求。那么我们可能就要设置ScaleType了,但是在试过了所有类型之后,也都满足不了我们的要求,要不就是只能显示一部分,要不就是宽度不能填充,或者是不能居中显示。为此,我们可以试一试自定义控件。

我们可以设置ScaleType为centerCrop,还记得centerCrop是什么意思么?以图片几何中心为基准,放缩短边至填充满。这样做的话,第一个填充效果就可以实现了,剩下的就是要高度自适应了。

我第一次在做这个功能的时候,走入了一个误区。

第一个思路就是,重写ImageView的setBitmap和setDrawable方法,在设置之后,获取bitmap,然后计算ImageView的宽度和bitmap的比例,以此比例计算bitmap的高度,然后生成新的Bitmap对象,设置给ImageView,设置之后,调用requestLayout(),重新布局,完成高度的改变。首先,使用这个方案是完全能解决问题的,计算完之后,重新布局,可以使得高度自适应,但是,你发现问题了吗?我在计算高度之后,又重新生成了Bitmap对象,而这一步是使用下面的方法完成的

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"> Matrix matrix = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Matrix();
 matrix.postScale(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.5f</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.5f</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//长和宽放大缩小的比例</span>
 Bitmap resizeBmp  = Bitmap.createBitmap(bitmap,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,Width,height,matrix,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

在这个操作里面,使用到了矩阵,而矩阵计算会占用大量cpu时间,因此,当我这么完成之后,慢慢滑动列表是没有问题的,但是当我疯狂的快速滑动的时候,就会出现非常明显的卡顿。

那么怎么解决这个问题呢?其实我后来看代码,完全没必要再生成新的Bitmap,只计算合适的高度就可以完成我们的需求,因此,修改之后的代码如下

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * 自定义控件,用于显示宽度和ImageView相同,高度自适应的图片显示模式.
 * 除此之外,还添加了最大高度限制,若图片长度大于等于屏幕长度,则高度显示为屏幕的1/3
 * Created by zhaokaiqiang on 15/4/20.
 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ShowMaxImageView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ImageView</span> {</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mHeight = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShowMaxImageView</span>(Context context) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShowMaxImageView</span>(Context context, AttributeSet attrs) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShowMaxImageView</span>(Context context, AttributeSet attrs, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> defStyleAttr) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs, defStyleAttr);
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setImageBitmap</span>(Bitmap bm) {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (bm != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            getHeight(bm);
        }

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.setImageBitmap(bm);
        requestLayout();
        invalidate();
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setImageDrawable</span>(Drawable drawable) {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (drawable != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            getHeight(drawableToBitamp(drawable));
        }

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.setImageDrawable(drawable);
        requestLayout();
        invalidate();
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> heightMeasureSpec) {


        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mHeight != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resultHeight = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) Math.max(mHeight, sizeHeight);

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (resultHeight >= ScreenSizeUtil.getScreenHeight((Activity) getContext())) {
                resultHeight = ScreenSizeUtil.getScreenHeight((Activity) getContext()) / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
            }

            setMeasuredDimension(sizeWidth, resultHeight);
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }

    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">getHeight</span>(Bitmap bm) {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> bitmapWidth = bm.getWidth();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> bitmapHeight = bm.getHeight();

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (bitmapWidth > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && bitmapHeight > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> scaleWidth = getWidth() / bitmapWidth;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (scaleWidth != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                mHeight = bitmapHeight * scaleWidth;
            }
        }

    }


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Bitmap <span class="hljs-title" style="box-sizing: border-box;">drawableToBitamp</span>(Drawable drawable) {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (drawable != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bd.getBitmap();
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
        }
    }

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li></ul>

使用上面的代码之后,我们就完成了图片的完整显示,而且没有任何的性能问题,至此,问题解决。

评论的“楼中楼”、“多楼隐藏”效果实现

在讲解具体实现之前,我们需要先了解一下评论列表的数据结构。

我们以这个测试接口为例:http://jandan.duoshuo.com/api/threads/listPosts.json?thread_key=comment-2750904

因为数据太多,我就不在这里粘贴了,大家自己打开看就可以。

煎蛋使用的是多说的评论接口,所以获取接口都是从多说获取。

从上往下的标签意义如下:

  • hotPosts 热门评论
  • thread 当前被评论主体的信息,包括thread_id、thread_key、url、comments等重要数据
  • cursor 总数和评论页码
  • parentPosts 所有的具体评论数据
  • response 参与回复的所有主体的id
  • options 可选属性,暂时无用

我们需要重点关注的是hotPosts、parentPosts。

在了解我们要显示的数据结构之后,我们就要思考如何去实现我们的评论列表的效果。

第一个问题是,如何添加“热门评论”、“最新评论”的分割标志,并对评论进行分类。 
这一步我实在自定义Request里面完成的,为了完成这个跟功能,我们需要一个评论的实体类,下面是重要字段

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//评论内容标签</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG_HOT = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hot"</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG_NORMAL = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"normal"</span>;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//评论布局类型</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> TYPE_HOT = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> TYPE_NEW = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> TYPE_NORMAL = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String avatar_url;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String created_at;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String name;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String message;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//评论发送者id</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String post_id;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这条评论所回复的评论id</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String parent_id;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这条评论上的所有评论id</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String[] parents;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//所属楼层</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> floorNum;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用于标示是否是热门评论</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String tag;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用于区别布局类型:热门评论、最新评论、普通评论</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> type;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>

我们需要内容标签和布局类型,热门评论需要单独筛选出来显示,其他评论按照时间排序,算作最新评论,下面是自定义的Request的实现

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Created by zhaokaiqiang on 15/4/10.
 */</span>
public class Request4CommentList extends Request<ArrayList<Commentator>> {

    private Response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Listener</span><ArrayList<Commentator>> listener<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    private LoadFinishCallBack callBack<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    public Request4CommentList(String url, Response
            <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Listener</span><ArrayList<Commentator>> listener,
                               Response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ErrorListener</span> errorListener,LoadFinishCallBack callBack) {
        super(Method<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.GET</span>, url, errorListener)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        this<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.listener</span> = listener<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        this<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.callBack</span> = callBack<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }

    @Override
    protected Response<ArrayList<Commentator>> parseNetworkResponse(NetworkResponse response) {

        try {
            //获取到所有的数据
            String jsonStr = new String(response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.data</span>, HttpHeaderParser<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseCharset</span>(response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.headers</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            //解析出所有的thread_id,并去掉非法字符,便与解析
            JSONObject resultJson = new JSONObject(jsonStr)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            String allThreadId = resultJson<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"response"</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"["</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"]"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\""</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            String[] threadIds = allThreadId<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.split</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\\,"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

            callBack<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.loadFinish</span>(resultJson<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optJSONObject</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"thread"</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"thread_id"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

            if (TextUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isEmpty</span>(threadIds[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])) {
                return Response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.success</span>(new ArrayList<Commentator>(), HttpHeaderParser
                        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseCacheHeaders</span>(response))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            } else {

                //然后根据thread_id再去获得对应的评论和作者信息
                JSONObject parentPostsJson = resultJson<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getJSONObject</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"parentPosts"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                //找出热门评论
                String hotPosts = resultJson<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hotPosts"</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"["</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>
                        (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"]"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\""</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                String[] allHotPosts = hotPosts<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.split</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\\,"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                ArrayList<Commentator> commentators = new ArrayList<>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                List<String> allHotPostsArray = Arrays<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.asList</span>(allHotPosts)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                for (String threadId : threadIds) {
                    Commentator commentator = new Commentator()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    JSONObject threadObject = parentPostsJson<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getJSONObject</span>(threadId)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                    //解析评论,打上TAG
                    if (allHotPostsArray<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.contains</span>(threadId)) {
                        commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTag</span>(Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TAG</span>_HOT)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    } else {
                        commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTag</span>(Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TAG</span>_NORMAL)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    }

                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setPost</span>_id(threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"post_id"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setParent</span>_id(threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"parent_id"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                    String parentsString = threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"parents"</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"["</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>
                            (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"]"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\""</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                    String[] parents = parentsString<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.split</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\\,"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setParents</span>(parents)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                    //如果第一个数据为空,则只有一层
                    if (TextUtil<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isNull</span>(parents[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])) {
                        commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFloorNum</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    } else {
                        commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFloorNum</span>(parents<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.length</span> + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    }

                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setMessage</span>(threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"message"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCreated</span>_at(threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"created_at"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    JSONObject authorObject = threadObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optJSONObject</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"author"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setName</span>(authorObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAvatar</span>_url(authorObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.optString</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"avatar_url"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setType</span>(Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TYPE</span>_NORMAL)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    commentators<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(commentator)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                }

                return Response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.success</span>(commentators, HttpHeaderParser<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseCacheHeaders</span>(response))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            }
        } catch (Exception e) {
            e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            return Response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.error</span>(new ParseError(e))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }

    }

    @Override
    protected void deliverResponse(ArrayList<Commentator> response) {
        listener<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onResponse</span>(response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }

}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li></ul>

我们在parseNetworkResponse方法里面完成了所有的数据解析,并且将热门评论打上tag区分开来,同时根据parents字段对应的数组长度,判断出当前楼层,至此,我们的数据就准备好了。

那么,解析完数据之后,应该怎么做呢?

我们来看一下请求完之后的回调做了什么。

在Adapter中,我封装了加载数据的方法loadData()。

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loadData</span>() {
            executeRequest(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Request4CommentList(Commentator.getUrlCommentList(thread_key), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Response
                    .Listener<ArrayList<Commentator>>() {
                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onResponse</span>(ArrayList<Commentator> response) {

                    google_progress.setVisibility(View.GONE);
                    tv_error.setVisibility(View.GONE);

                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (response.size() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                        tv_no_thing.setVisibility(View.VISIBLE);
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                        commentators.clear();

                        ArrayList<Commentator> hotCommentator = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>();
                        ArrayList<Commentator> normalComment = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>();

                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//添加热门评论</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Commentator commentator : response) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (commentator.getTag().equals(Commentator.TAG_HOT)) {
                                hotCommentator.add(commentator);
                            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                                normalComment.add(commentator);
                            }
                        }

                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//添加热门评论标签</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (hotCommentator.size() != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                            Collections.sort(hotCommentator);
                            Commentator hotCommentFlag = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Commentator();
                            hotCommentFlag.setType(Commentator.TYPE_HOT);
                            hotCommentator.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, hotCommentFlag);
                            commentators.addAll(hotCommentator);
                        }

                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//添加最新评论及标签</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (normalComment.size() != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                            Commentator newCommentFlag = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Commentator();
                            newCommentFlag.setType(Commentator.TYPE_NEW);
                            commentators.add(newCommentFlag);
                            Collections.sort(normalComment);
                            commentators.addAll(normalComment);
                        }

                        mAdapter.notifyDataSetChanged();
                    }
                    mSwipeRefreshLayout.setRefreshing(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);

                }
            }, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Response.ErrorListener() {
                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onErrorResponse</span>(VolleyError error) {
                    mSwipeRefreshLayout.setRefreshing(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
                    google_progress.setVisibility(View.GONE);
                    tv_error.setVisibility(View.VISIBLE);
                    tv_no_thing.setVisibility(View.GONE);
                }
            }, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LoadFinishCallBack() {
                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loadFinish</span>(Object obj) {
                    thread_id = (String) obj;
                }
            }));
        }


    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li></ul>

在这段代码里面,我们先清空了commentators,这个集合里面将防止我们处理好的数据。我创建了hotCommentator和normalComment两个集合,分别用来存放热门评论和一般评论。整个评论列表是通过RecycleView来做的,我们都知道ListView支持多种布局类型,RecycleView也一样,我们可以根据hotCommentator和normalComment这两个集合的长度来决定是否添加热门评论和最新评论是否显示,如果显示的话,添加一个设置好Type的Commentator对象即可。由于需要使用Collections.sort()进行排序,所以我们的实体类需要实现Comparable接口,然后根据发布时间排序

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">@Override
    public int compareTo(Object another) {

        String anotherTimeString = ((Commentator) another)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getCreated</span>_at()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"T"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        anotherTimeString = anotherTimeString<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.substring</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, anotherTimeString<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.indexOf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"+"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

        String thisTimeString = getCreated_at()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"T"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        thisTimeString = thisTimeString<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.substring</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, thisTimeString<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.indexOf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"+"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"yyyy-MM-dd HH:mm:ss"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        simpleDateFormat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTimeZone</span>(TimeZone<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTimeZone</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"GMT+08"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

        try {
            Date anotherDate = simpleDateFormat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parse</span>(anotherTimeString)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            Date thisDate = simpleDateFormat<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parse</span>(thisTimeString)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            return -thisDate<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.compareTo</span>(anotherDate)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        } catch (ParseException e) {
            e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            return <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

那么怎么实现多种布局呢? 
首先,需要实现getItemViewType方法,如下

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">@Override
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getItemViewType</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> commentators.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>(position).getType();
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

设置好ViewType之后,我们在onCreateViewHolder里面就可以根据viewType生成ViewHolder了

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> ViewHolder <span class="hljs-title" style="box-sizing: border-box;">onCreateViewHolder</span>(ViewGroup parent, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> viewType) {

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (viewType) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> Commentator.TYPE_HOT:
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> Commentator.TYPE_NEW:
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ViewHolder(getLayoutInflater().inflate(R.layout
                                    .item_comment_flag, parent,
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> Commentator.TYPE_NORMAL:
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ViewHolder(getLayoutInflater().inflate(R.layout.item_comment, parent,
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">default</span>:
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
            }
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

需要注意的是,我们在创建我们自己的ViewHolder的时候,需要把所有布局里面用到的View都绑定好,如下

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewHolder</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">RecyclerView</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewHolder</span> {</span>

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> TextView tv_name;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> TextView tv_content;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> TextView tv_time;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LinearLayout ll_vote;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SimpleDraweeView img_header;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> FloorView floors_parent;

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> TextView tv_flag;

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ViewHolder</span>(View itemView) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(itemView);
            tv_name = (TextView) itemView.findViewById(R.id.tv_name);
            tv_content = (TextView) itemView.findViewById(R.id.tv_content);
            tv_time = (TextView) itemView.findViewById(R.id.tv_time);
            ll_vote = (LinearLayout) itemView.findViewById(R.id.ll_vote);
            img_header = (SimpleDraweeView) itemView.findViewById(R.id.img_header);
            floors_parent = (FloorView) itemView.findViewById(R.id.floors_parent);

            tv_flag = (TextView) itemView.findViewById(R.id.tv_flag);

            setIsRecyclable(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);

        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

其实tv_flag在正常布局里面没有这个TextView,只存在于评论的分割布局里面,但是我们同样需要在这里find出来,否则没法使用。

至于这个setIsRecyclable(false)则是设置当前的ViewHolder不能够复用,因为在这里复用会导致布局混乱,不复用肯定会效率低一些,但是我还没找到其他好的解决方案。

这些工作做完之后,我们就需要在onBindViewHolder里面进行数据绑定了。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">@Override
        public void onBindViewHolder(ViewHolder holder, int position) {

            final Commentator commentator = commentators<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.get</span>(position)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

            switch (commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getType</span>()) {
                case Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TYPE</span>_HOT:
                    holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tv</span>_flag<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"热门评论"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                case Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TYPE</span>_NEW:
                    holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tv</span>_flag<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"最新评论"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                case Commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TYPE</span>_NORMAL:
                    holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tv</span>_name<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tv</span>_content<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMessage</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                    ...

                    //有楼层,盖楼
                    if (commentator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getFloorNum</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                        SubComments cmts = new SubComments(addFloors(commentator))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setComments</span>(cmts)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFactory</span>(new SubFloorFactory())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setBoundDrawer</span>(getResources()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDrawable</span>(
                                R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawable</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bg</span>_comment))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.init</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    } else {
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setVisibility</span>(View<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.GONE</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    }

                    ...

                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            }

        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>

为了更清晰,我在中间省去了很多代码,前两个case就是填充我们的评论类型分割布局,第三个case则是真正的评论数据的填充,在这里我们就实现了“楼中楼”和“多楼隐藏”效果。

在开始正式介绍之前,我简单的介绍下实现的思路。

首先,我们完成这个效果,需要自定义一个Linearlayout,当只有一层楼时,我们隐藏它,如果有盖楼效果,我们需要把所有的楼层放到这个LinearLayout里面,评论内容放在TextView里面,楼层的外框需要我们单独画出。

下面是评论布局的xml文件

<code class="hljs xml has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:fresco</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res-auto"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/left"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"56.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"vertical"</span>
        ></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">com.facebook.drawee.view.SimpleDraweeView
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/img_header"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"40dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"40dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">fresco:roundedCornerRadius</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"5dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">fresco:placeholderImage</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@drawable/ic_loading_small"</span>
            /></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/right"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toEndOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingEnd</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingRight</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingStart</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0.0dip"</span>></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">View
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/left_placeholder"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"1.0dip"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:visibility</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"visible"</span>/></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/tv_name"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left_placeholder"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:ellipsize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"end"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:singleLine</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"AAAAAAAAAA"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:maxLength</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"10"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/primary_text_default_material_light"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"15.0sp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textStyle</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"bold"</span>/></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/tv_time"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_alignBaseline</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/tv_name"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8.0dip"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/tv_name"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"2 mins ago"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/secondary_text_default_material_light"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"13.0sp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:visibility</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"visible"</span>/></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">com.socks.jiandan.view.floorview.FloorView
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/floors_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left_placeholder"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_below</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/tv_name"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@drawable/bg_floor"</span>
            /></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/tv_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_below</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/floors_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left_placeholder"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:lineSpacingExtra</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"4dp"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"aaa"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/primary_text_default_material_light"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"14sp"</span>/></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/ll_vote"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_alignBottom</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/tv_name"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_alignParentRight</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"right"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"horizontal"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:visibility</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"visible"</span>></span>

            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout
</span>                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/support"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"horizontal"</span>></span>

                <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/like_descr"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"center"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"OO "</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/secondary_text_default_material_light"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"13.0sp"</span>/></span>

                <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/like"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"center"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/secondary_text_default_material_light"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"13.0sp"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textStyle</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"normal"</span>/></span>
            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>

            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout
</span>                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/unsupport"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"horizontal"</span>></span>

                <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/unlike_descr"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"center"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"   XX "</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/secondary_text_default_material_light"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"13.0sp"</span>/></span>

                <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/unlike"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"center"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@color/secondary_text_default_material_light"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"13.0sp"</span>
                    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textStyle</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"normal"</span>/></span>
            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span>></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">View
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/divider"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"fill_parent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"1.0px"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_below</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/right"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"16.0dip"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toEndOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@id/left"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#ffd9d9d9"</span>/></span>

<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li><li style="box-sizing: border-box; padding: 0px 5px;">152</li><li style="box-sizing: border-box; padding: 0px 5px;">153</li><li style="box-sizing: border-box; padding: 0px 5px;">154</li><li style="box-sizing: border-box; padding: 0px 5px;">155</li><li style="box-sizing: border-box; padding: 0px 5px;">156</li><li style="box-sizing: border-box; padding: 0px 5px;">157</li><li style="box-sizing: border-box; padding: 0px 5px;">158</li><li style="box-sizing: border-box; padding: 0px 5px;">159</li><li style="box-sizing: border-box; padding: 0px 5px;">160</li><li style="box-sizing: border-box; padding: 0px 5px;">161</li><li style="box-sizing: border-box; padding: 0px 5px;">162</li></ul>

tv_content是评论内容,floors_parent则是我们自定义的控件,我们重点看下这个是如何实现的。

完成整个盖楼功能,需要三个类,如下

  • FloorView 自定义LinearLayout,完成楼层的内容填充、分割线绘制和布局添加
  • SubComments 对评论的再次封装,每一个评论都对应一个SubComments对象,它里面封装个这个评论的所有楼层内容
  • SubFloorFactory Floor工厂,用于根据不同类型产生正常评论View和隐藏楼层View,同时在产生过程中,完成了数据和View的适配

介绍完这三个类,我们看下用法

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">
                        SubComments cmts = new SubComments(addFloors(commentator))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setComments</span>(cmts)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFactory</span>(new SubFloorFactory())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setBoundDrawer</span>(getResources()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDrawable</span>(
                                R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawable</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bg</span>_comment))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        holder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.floors</span>_parent<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.init</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

上面的代码完整的展示了调用的流程。

首先生成一个SubComments数据封装对象,这里调用了一个addFloors方法,代码如下

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> List<Commentator> <span class="hljs-title" style="box-sizing: border-box;">addFloors</span>(Commentator commentator) {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//只有一层</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (commentator.getFloorNum() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
            }
            List<String> parentIds = Arrays.asList(commentator.getParents());
            List<Commentator> commentators = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Commentator comm : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.commentators) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (parentIds.contains(comm.getPost_id())) {
                    commentators.add(comm);
                }
            }

            Collections.reverse(commentators);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> commentators;
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

在addFloors里面其实我们就完成了一件事,那就是把当前commentator对象的所有父级对象都找出来,然后添加进集合后按时间排序,这样我们就能获取到一条评论的所有信息啦~

之后,我们又setComments、setFactory、setBoundDrawer,全部设置齐活,调用init()就出来了~

那么init到底做了些什么?下面是FloorView源码

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> JohnnyShieh
 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @ClassName</span>: FloorView
 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @Description</span>:
 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @date</span> Jan 25, 2014 2:09:36 PM
 */</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@TargetApi</span>(Build.VERSION_CODES.HONEYCOMB)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FloorView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LinearLayout</span> {</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> density;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Drawable drawer;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SubComments datas;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SubFloorFactory factory;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">FloorView</span>(Context context) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context);
        init(context);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">FloorView</span>(Context context, AttributeSet attrs) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs);
        init(context);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">FloorView</span>(Context context, AttributeSet attrs, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> defStyle) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs, defStyle);
        init(context);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setBoundDrawer</span>(Drawable drawable) {
        drawer = drawable;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setComments</span>(SubComments cmts) {
        datas = cmts;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setFactory</span>(SubFloorFactory fac) {
        factory = fac;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getFloorNum</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getChildCount();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(Context context) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.setOrientation(LinearLayout.VERTICAL);
        density = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) (<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3.0</span>F * context.getResources().getDisplayMetrics().density);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == datas.iterator())
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (datas.getFloorNum() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Iterator<Commentator> iterator = datas.iterator(); iterator
                    .hasNext(); ) {
                View view = factory.buildSubFloor(iterator.next(), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
                addView(view);
            }
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            View view;
            view = factory.buildSubFloor(datas.get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
            addView(view);
            view = factory.buildSubFloor(datas.get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
            addView(view);
            view = factory.buildSubHideFloor(datas.get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
            view.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnClickListener() {

                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) {
                    TextView hide_text = (TextView) v
                            .findViewById(R.id.hide_text);
                    hide_text.setCompoundDrawablesWithIntrinsicBounds(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,
                            <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
                    v.findViewById(R.id.hide_pb).setVisibility(View.VISIBLE);
                    removeAllViews();
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Iterator<Commentator> iterator = datas.iterator(); iterator
                            .hasNext(); ) {
                        View view = factory.buildSubFloor(iterator.next(),
                                FloorView.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
                        addView(view);
                    }
                    reLayoutChildren();
                }
            });
            addView(view);
            view = factory.buildSubFloor(datas.get(datas.size() - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
            addView(view);
        }

        reLayoutChildren();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">reLayoutChildren</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count = getChildCount();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < count; i++) {
            View view = getChildAt(i);
            LayoutParams layout = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.WRAP_CONTENT);
            layout.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> margin = Math.min((count - i - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) * density;
            layout.leftMargin = margin;
            layout.rightMargin = margin;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i == count - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                layout.topMargin = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                layout.topMargin = Math.min((count - i), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) * density;
            }
            view.setLayoutParams(layout);
        }
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">dispatchDraw</span>(Canvas canvas) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = getChildCount();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> != drawer && i > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = i - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j--) {
                View view = getChildAt(j);
                drawer.setBounds(view.getLeft(), view.getLeft(),
                        view.getRight(), view.getBottom());
                drawer.draw(canvas);
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.dispatchDraw(canvas);
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onLayout</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> changed, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> l, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> t, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> r, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onLayout(changed, l, t, r, b);
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> heightMeasureSpec) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.getChildCount() <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            setMeasuredDimension(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li></ul>

可以看到,在init()首先根据评论数量判断,是否隐藏,不隐藏,就调用SubFloorFactory的buildSubFloor创建一个楼层,要是隐藏呢?就创建一楼、二楼,然后创建一个隐藏楼层,然后创建最后一个楼层。创建完之后调用reLayoutChildren()。

<code class="hljs glsl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">public <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> reLayoutChildren() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count = getChildCount();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < count; i++) {
            View view = getChildAt(i);
            LayoutParams <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span> = new LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.WRAP_CONTENT);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> margin = Math.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span>((count - i - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) * density;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.leftMargin = margin;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.rightMargin = margin;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i == count - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.topMargin = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.topMargin = Math.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span>((count - i), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) * density;
            }
            view.setLayoutParams(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>);
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

在这里面,根据不同的楼层,设置不同的margin,从而显示出一层挨着一层的效果。

那么每一层的间隔线呢?是在dispatchDraw()里面实现的

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">dispatchDraw</span>(Canvas canvas) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = getChildCount();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> != drawer && i > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = i - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j--) {
                View view = getChildAt(j);
                drawer.setBounds(view.getLeft(), view.getLeft(),
                        view.getRight(), view.getBottom());
                drawer.draw(canvas);
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.dispatchDraw(canvas);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

通过重写dispatchDraw(),在画childView之前,先把边框绘制出来,这样就实现了边框效果。注意绘制顺序,super.dispatchDraw(canvas)需要在最后调用,否则会覆盖。

如果存在隐藏楼层,怎么点击全部显示出来呢?

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">view<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setOnClickListener</span>(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    TextView hide_text = (TextView) v
                            <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.findViewById</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>_text)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    hide_text<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCompoundDrawablesWithIntrinsicBounds</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,
                            <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    v<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.findViewById</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hide</span>_pb)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setVisibility</span>(View<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.VISIBLE</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    removeAllViews()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    for (Iterator<Commentator> iterator = datas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.iterator</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; iterator</span>
                            <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.hasNext</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; ) {</span>
                        View view = factory<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.buildSubFloor</span>(iterator<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.next</span>(),
                                FloorView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.this</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                        addView(view)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                    }
                    reLayoutChildren()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                }
            })<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>

在点击之后,首先removeAllViews(),然后创建了新的view,使用addView添加进去,最后reLayoutChildren()就可以了。

至此,“盖楼”效果就完全实现了。

因为文章太长了,所以剩下的内容只能放到下一篇了,写的好累呀,休息下~

别忘记去项目star一下哦

项目地址:https://github.com/ZhaoKaiQiang/JianDan

版权声明:本文为博主原创文章,未经博主允许不得转载。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:166072次
    • 积分:2957
    • 等级:
    • 排名:第13183名
    • 原创:77篇
    • 转载:325篇
    • 译文:0篇
    • 评论:12条
    博客专栏
    最新评论