如何在Android中正确地实现类似于Facebook/Instagram的Feed?

9

我对Android很陌生。我正在尝试创建一个包含许多图像和一些元数据的社交应用程序。它有一个类似于Facebook上的信息流屏幕。我希望使这个屏幕尽可能平滑和标准化。

这是我使用的库:OkHttp、Picasso、Retrofit、Gson。

现在,我正在一次性获取所有json数据,因为我已经在后端中提供了虚拟值,并且响应足够小。但是,将来,它将具有前一个和后一个字段来限制json响应。

我现在有一些问题:

  1. 我正在使用带有OkHttp的Picasso。它是否也会将图像缓存到磁盘中,还是只在内存中缓存?

  2. 关于缓存信息流的最佳实践是什么?由于大部分内容都是图片,我应该让Picasso处理缓存还是应该自己缓存一些项目?听说过JakeWharton的DiskLruCache库,但没有尝试过。我应该用它吗?

  3. 如何在滚动方向的任意一侧保持一些信息流内容(例如3或4)以进行缓存,以使滚动看起来平滑并且图像不会在进入视图后开始加载?

  4. 当用户滚动本次一次性获取的所有内容时如何自动处理json响应,使用前一个和后一个字段进行触发请求。基本上,我想根据游标触发请求。

  5. 假设有一个喜欢按钮,用户单击它,我应该在UI中更改喜欢数量并发送POST请求以更新计数器,还是应该发送请求并等待来自服务器的更新计数器再将其更新到UI中?

我已经查看了Instamaterial的源代码,并学到了一些惊人的东西。但它没有演示整个后端集成。

我只想知道是否有其他开源应用程序可以学习或学习。如果您知道任何教程也会很有帮助。我只是希望使应用程序体验尽可能平滑,并学习一些最佳实践。


在YouTube上有一个很好的系列视频,搜索“thenewboston”。 - XxGoliathusxX
@XxGoliathusxX,他们有一个通用的Android开发系列。如果您指的是某些特定的视频,请发布链接。 - Amit Tiwari
3个回答

7
  1. 这个库不仅会缓存在内存中,还会缓存到磁盘上。如果你将 Picasso 设置为调试模式,它会显示一个指示器,描述图片是从哪里加载的(内存/磁盘/网络)。
  2. 如果你不介意 Picasso 控制缓存时间等方面的内容,那么让它处理缓存应该是没问题的。我也相信 Picasso 使用了 DiskLruCache。
  3. 如果你最关心的是图片,它们都会被缓存起来,一旦加载过一次就不需要再次加载(直到更新)。你还可以在 Picasso 中注册回调函数,以改变占位符的显示或隐藏逻辑。
  4. 我认为你要找的是列表视图的滚动监听器(我假设你在使用列表视图)。当它超过一定位置(5/6)时,开始加载接下来的10项。如果你使用 RecyclerView,你可以在滚动监听器中使用 onScrollStateChanged 函数,并使用 LinearLayoutManager 来调用 findLastVisibleItemPosition。
  5. 无论你选择哪种方法,都应该没有太大影响。如果你认为更新服务器计数器需要很长时间(实际上不应该),那么最好先在本地更新它。

对于第四点,假设在JSON响应中,我得到了10个项目,并且有标准字段用于下一个和上一个,当附加到API查询时,将获取前一个或下一个10个项目。如何确保用户一旦看到第8或第9个项目并继续滚动(意味着他想查看更多项目),我就会获取下一个10个项目。这类似于Facebook应用程序的情况。 - Amit Tiwari
我已经更新了我的答案,我认为这就是你要找的。 - Marcus Hooper
是的,没错。只有一点区别,我正在使用RecyclerView。我还没有见过或编写过任何这方面的代码。如果您知道任何好的教程或解释,请发送链接。谢谢。 - Amit Tiwari
我不确定有没有适合你所需的好教程。如果你想在RecyclerView中复制相同的功能,可以使用以下代码:recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() == 5) //加载更多项目 } }); - Marcus Hooper

3

1. 我建议您查看Facebook的图像管理库Fresco,相比其他图像加载库,它非常出色和成熟。Fresco

2. Fresco使用3层架构(BITMAP_MEMORY_CACHEENCODED_MEMORY_CACHEDISK_CACHE)处理所有图像缓存,并减少OOM(内存不足)问题。当视图中的图像超出屏幕时,它会自动回收位图,从而释放内存。

3. 为此,您需要实现分页。确实,您可能需要发送先前记录项的位置或索引,以便可以获取其后继项目。

4. 为了为用户提供平滑的应用体验,您应该同时增加计数器并向后端发送POST请求。

您还可以查看这个教程 Facebook like Feed


我已经检查了Fresco,但我发现与Picasso和Glide相比,其语法有点复杂。而且Picasso可以高效地处理我的大部分需求。如果我在使用Picasso时遇到任何性能损失,我肯定会尝试使用Fresco。除了图片之外,我是否应该使用DiskLruCache缓存其他元数据,例如用户名、点赞数等?另外,由于Picasso自己正在缓存图像,我是否需要使用DiskLruCache单独缓存它们呢? - Amit Tiwari
@AmitTiwari,我一开始也说了同样的话,但是现在我更倾向于你使用Fresco,因为我在处理某些JPG和PNG图像时遇到了一些问题。Picasso会出错,而Fresco在相同的图像上运行良好。所以从现在开始请使用Fresco。 - MBH
@MBH 我会去查看的。 - Amit Tiwari
1
@AmitTiwari 当然,使用Fresco可能有点复杂,但当你开始使用它时,你会理解它的真正威力 :) - Vipul Asri

3

我会为你提供一些解决问题的方法:

处理JSON:

您可以使用名为Retrofit的库,这样在服务器端添加和删除内容将更容易在Android客户端中处理。只需在Java类中删除或添加变量即可!

缓存图像:

我建议您使用Fresco,Facebook的库,它将大大简化您的工作。因为它可以处理圆角转换、下载进度条、循环图像和许多其他功能。因此,不仅可以为您处理内存和磁盘缓存,而且可以更好地处理不同的图像格式。

(我在上一个项目中使用了Picasso,有些图片和一些URI不能正常工作,我尝试了Picasso、Glide和Universal Image Loader,在完全相同的图像和相同的链接上,只有Fresco可以正常工作)

这不是针对您的问题的确切答案,但是我想分享我与这些库的经验,这可能会帮助您。


1
谢谢。我一定会尝试使用Fresco。 - Amit Tiwari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接