RecyclerView实现优雅的瀑布流图片加载

开篇


这是我在简书上写的第一篇博客。非常喜欢简书的风格,所以想在这里写下我Android之路所遇到的一些麻烦,和我如何解决这一问题。

<small>之前一直使用ListView和GridView来应用在开发中,但是一直仰慕RecyclerView的大名,故开始踏上了RecyclerView的使用之旅。在使用过程中是遇到了很多的坑,比如说给RecyclerView 加上事件监听,我直接在RecyclerView上add了一个监听事件,可是程序运行之后却发现并没有事件回调出来。。。后来才知道RecyclerView并没有提供相应的接口,比如ClickListener和LongClickListener。我不明白为什么谷歌为什么这么做,可能是为了让他更能专注于他的技能Recycler吧。
  好了接下来是正题,大家都知道开发中我们常常使用RecyclerView实现三种布局管理,分别是LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager,前两种一般是没什么太大问题,今天我们来说说第三种瀑布流的实现方式。</small>

*这是我们最基础的用法,添加瀑布流3列垂直分布

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager );
adapter = new MyRecyclerAdapter();
recyclerView.setAdapter(adapter);

这里我根据图片数量给他设置一些随机高度,因为我使用的接口并没有返回图片的宽高

List<Integer> heights = new ArrayList<>();
for (int i = 0; i < urls.size(); i++) {
  int x=random.nextInt(200) + 200;
  heights.add(x);
}

并在onBindViewHolder中设置itemView的高度

StaggeredGridLayoutManager.LayoutParams layoutParams =
(StaggeredGridLayoutManager.LayoutParams) itemView.getLayoutParams();
layoutParams.height = heights.get(position);
itemView.setLayoutParams(layoutParams);
我放入了一些测试数据,并使用了Picasso加载图片

<img src="http://upload-images.jianshu.io/upload_images/2826360-0485125ee3747b15.gif?imageMogr2/auto-orient/strip" style="zoom:50%"/>

我们发现被滑出屏幕的图片又消失被重新加载了

这是什么原因呢

<small>给bindView打上日志,发现itemView一旦划入可见区域,便会调用onBindViewHolder方法...于是Picasso又给我们的图片重新加载了一遍</small>

这里我的思路是:

  • 设置ImageView的tag,可以设置tag为position或者url。
  • 在加载图片的时候先进行判断是否有tag,没有tag进行图片加载
        @Override
        public void onBindViewHolder(MyRecyclerViewHolder holder, final int position) {
            if (holder.itemView.getTag() == null) {
                holder.itemView.setTag(position);
                holder.bind(position);
            }
        }

这样就不会重复加载了,不知道是否有更加合理的方式,有请告知,感激不尽。

接下来我们的效果是

autoChangeItem.gif

这里的问题可愁了我了……
网上查了好久都没有发现好的文章能真正帮我解决这个问题
最终放弃寻求别人帮助,还是靠自己解决吧。。。
我决定对RecyclerView的Adapter进行拆解,对他的各种可能需要用到的方法进行日志打印,我相信create和bind方法两个肯定是打上了日志,最终我发现每次itemView自动交换位置的时候,onCreateViewHolder这个方法就会被调用。哪里有问题点哪里。。。我们来看一下源码中,对onCreateViewHolder的描述,我截取了最为重要的部分

* @param parent The ViewGroup into which the new View will be added after it is bound to
*               an adapter position.
* @param viewType The view type of the new View.
*
* @return A new ViewHolder that holds a View of the given view type.
* @see #getItemViewType(int)
* @see #onBindViewHolder(ViewHolder, int)

<small>可见RecyclerView真的很灵活,他根据你返回的View类型来决定create一个新的视图的类型,我想问题出在这里,默认返回的是0,当我从下往上滑到最顶部的时候,复用的View大小是根据下面的itemView的大小,所以高度上出现了不适应,layoutManager会自动调整位置,于是出现了上述情况</small>

我们重写getItemViewType方法,让我们的高度成为type的值

@Override
public int getItemViewType(int position) {
     return heights.get(position);
//   return super.getItemViewType(position);
}

OK,我们进行一下测试。


last.gif

至此我们实现了瀑布流图片加载

  但是还不够优雅,因为我相信,我在这里使用图片的高度作为ViewType肯定是有问题的,因我的图片高度太多不固定的值,有的是重复的,但是大多数是不重复的,这势必会造成性能问题。所以建议在使用瀑布流的时候,不要用太多不同的高度,适度就行。。。一般是根据图片的大小来计算。

当然具体情况还是得具体对待……

结束语:我对于网上某些写的RecyclerView的文章还是要说一句,多一些真诚,少一些CV。
文章中如有什么错误,请您谅解并且可以给我留言指出,写了好久,休息休息。Thanks!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,123评论 6 528
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,850评论 3 412
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 174,839评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,389评论 1 308
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,183评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,717评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,797评论 3 436
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,951评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,459评论 1 330
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,431评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,573评论 1 365
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,123评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,823评论 3 344
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,220评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,475评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,155评论 3 387
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,560评论 2 370

推荐阅读更多精彩内容