有人知道如何在 android 中实现延迟加载 recyclerView 吗?我是 android 的新手,我不知道如何解决这个问题。如果有人提供帮助,我将不胜感激。
最佳答案
你可以使用 EndlessRecyclerView
概览 一个常见的应用程序功能是在用户滚动项目时自动加载更多项目(也称为无限滚动)。这是通过在用户超过剩余项目的阈值后触发更多数据请求来完成的。
此处记录了 ListView、GridView 和 RecyclerView(ListView 的后继者)的方法。两者代码相似,只是需要传入RecyclerView中的LayoutManager,提供实现无限滚动的必要信息。
在这两种情况下,实现滚动所需的信息包括确定列表中的最后一个可见项目和某种类型的阈值以在到达最后一个项目之前开始获取更多数据。此数据可用于决定何时从外部源加载更多数据: To provide the appearance of endless scrolling, it's important to fetch data before the user gets to the end of the list. Adding a threshold value therefore helps anticipate the need to append more data.
使用 ListView 或 GridView 实现
每个 AdapterView(例如 ListView 和 GridView)都支持绑定(bind)到 OnScrollListener 事件,只要用户滚动浏览集合就会触发这些事件。使用这个系统,我们可以定义一个基本的 EndlessScrollListener,它通过创建我们自己的扩展 OnScrollListener 的类来支持大多数用例:
import android.widget.AbsListView;
public abstract class EndlessScrollListener implements AbsListView.OnScrollListener {
// The minimum number of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
public EndlessScrollListener() {
}
public EndlessScrollListener(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}
public EndlessScrollListener(int visibleThreshold, int startPage) {
this.visibleThreshold = visibleThreshold;
this.startingPageIndex = startPage;
this.currentPage = startPage;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) { this.loading = true; }
}
// If it's still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
currentPage++;
}
// If it isn't currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount ) {
loading = onLoadMore(currentPage + 1, totalItemCount);
}
}
// Defines the process for actually loading more data based on page
// Returns true if more data is being loaded; returns false if there is no more data to load.
public abstract boolean onLoadMore(int page, int totalItemsCount);
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Don't take any action on changed
}
}
请注意,这是一个抽象类,为了使用它,您必须扩展这个基类并定义 onLoadMore 方法来实际检索新数据。我们现在可以在任何扩展 EndlessScrollListener 的 Activity 中定义一个匿名类并将其绑定(bind)到 AdapterView。例如:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// ... the usual
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Attach the listener to the AdapterView onCreate
lvItems.setOnScrollListener(new EndlessScrollListener() {
@Override
public boolean onLoadMore(int page, int totalItemsCount) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to your AdapterView
loadNextDataFromApi(page);
// or loadNextDataFromApi(totalItemsCount);
return true; // ONLY if more data is actually being loaded; false otherwise.
}
});
}
// Append the next page of data into the adapter
// This method probably sends out a network request and appends new data items to your adapter.
public void loadNextDataFromApi(int offset) {
// Send an API request to retrieve appropriate paginated data
// --> Send the request including an offset value (i.e `page`) as a query parameter.
// --> Deserialize and construct new model objects from the API response
// --> Append the new data objects to the existing set of items inside the array of items
// --> Notify the adapter of the new items made with `notifyDataSetChanged()`
}
}
现在当您滚动时,项目将自动填充,因为一旦用户超过 visibleThreshold 就会触发 onLoadMore 方法。这种方法同样适用于 GridView,监听器可以访问页面和 totalItemsCount,以支持分页和基于偏移量的抓取。
使用 RecyclerView 实现
我们可以通过定义一个需要实现 onLoadMore() 方法的接口(interface) EndlessRecyclerViewScrollListener 来对 RecyclerView 使用类似的方法。 LayoutManager 负责在 RecyclerView 中呈现项目应放置的位置并管理滚动,提供有关当前滚动位置相对于适配器的信息。出于这个原因,我们需要传递一个 LayoutManager 的实例来收集必要的信息以确定何时加载更多数据。
为 RecyclerView 实现无限分页需要以下步骤:
为 RecyclerView 实现无限分页需要以下步骤:
1. 将 EndlessRecyclerViewScrollListener.java 复制到您的应用程序中。
2. 在 RecyclerView 上调用 addOnScrollListener(...) 以启用无限分页。传入一个 EndlessRecyclerViewScrollListener 实例并实现 onLoadMore,只要需要加载新页面以填充列表,它就会触发。
3. 在上述 onLoadMore 方法中,通过发送网络请求或从其他来源加载额外的项目到适配器中。
要开始处理步骤 2 和 3 的滚动事件,我们需要在 Activity 或 Fragment 中使用 addOnScrollListener() 方法,并使用布局管理器传入 EndlessRecyclerViewScrollListener 的实例,如下所示:
public class MainActivity extends Activity {
// Store a member variable for the listener
private EndlessRecyclerViewScrollListener scrollListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Configure the RecyclerView
RecyclerView rvItems = (RecyclerView) findViewById(R.id.rvContacts);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rvItems.setLayoutManager(linearLayoutManager);
// Retain an instance so that you can call `resetState()` for fresh searches
scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to the bottom of the list
loadNextDataFromApi(page);
}
};
// Adds the scroll listener to RecyclerView
rvItems.addOnScrollListener(scrollListener);
}
// Append the next page of data into the adapter
// This method probably sends out a network request and appends new data items to your adapter.
public void loadNextDataFromApi(int offset) {
// Send an API request to retrieve appropriate paginated data
// --> Send the request including an offset value (i.e `page`) as a query parameter.
// --> Deserialize and construct new model objects from the API response
// --> Append the new data objects to the existing set of items inside the array of items
// --> Notify the adapter of the new items made with `notifyItemRangeInserted()`
}
}
https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView
关于android - 在 android 中延迟加载 recyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35901697/
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述
如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail
我需要做这样的事情classUser'User',:foreign_key=>'abuser_id'belongs_to:gameendclassGame['JOINabuse_reportsONusers.id=abuse_reports.abuser_id','JOINgamesONgames.id=abuse_reports.game_id'],:group=>'users.id',:select=>'users.*,count(distinctgames.id)ASgame_count,count(abuse_reports.id)asabuse_report_count',:
我指的是pubrailscasttutorial并已正确执行所有步骤,但在运行最后一个命令时,即rackupprivate_pub.ru-sthin-Eproduction为了架设faye服务器,我收到以下错误:/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require':cannotloadsuchfile--thin(LoadError)from/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/var/lib/gems/1.9.1/gems
我们在服务器端遇到libxml-rubygem的问题可能是因为它使用x86_64架构:$uname-aLinuxip-10-228-171-642.6.21.7-2.fc8xen-ec2-v1.0#1SMPTueSep110:25:30EDT2009x86_64GNU/Linuxrequire'libxml'LoadError:/usr/local/ruby-enterprise/lib/ruby/gems/1.8/gems/libxml-ruby-1.1.4/lib/libxml_ruby.so:invalidELFheader-/usr/local/ruby-enterprise/