Android: 如何在recyclerView后台加载更多数据
Android: How can I load more data in the background in recyclerView
我正在创建一个新的 android 应用程序,我几乎完成了第一个屏幕。但是,当我到达屏幕底部时,应用程序并没有加载新数据,而是将我直接带到了页面的开头。
我正在使用的API会在我发送第二页请求时发送下一页。你能告诉我如何让应用程序在用户到达第一页末尾之前自动发送第二页请求吗?
我正在使用 volley 库以及 recyclerView 和 cardView。能否请您解释清楚我应该在哪里进行更改,我是应用程序开发的新手。
这里是截击请求:
private void discoverMovies() {
final ProgressDialog progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Fetching Data From DB");
progressDialog.show();
//Requesting the data.....
StringRequest stringRequest = new StringRequest(Request.Method.GET, tempURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
progressDialog.dismiss();
JSONObject parentObject = new JSONObject(response);
JSONArray parentArray = parentObject.getJSONArray("results");
for (int i = 0; i < parentArray.length(); i++) {
JSONObject object = parentArray.getJSONObject(i);
movieModel model = new movieModel(
object.getString("title"),
object.getString("overview"),
object.getString("release_date"),
object.getString("poster_path"),
object.getInt("id"),
object.getBoolean("adult"),
object.getInt("vote_count"),
object.getDouble("vote_average"),
object.getString("original_language"),
object.getString("backdrop_path")
);
movieModels.add(model);
adapter = new cardViewAdapter(getContext(), movieModels);
recyclerView.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(stringRequest);
}
对于分页,我使用以下代码
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (hasMoreRequest) {
if (dy > 0) { //check for scroll down
checkForMoreLoad();
}
}
}
});
private void checkForMoreLoad() {
final Handler handler = new Handler();
Runnable checkForMoreData = new Runnable() {
@Override
public void run() {
if (null != recyclerView) {
int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
int pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
onScrollToLoad(visibleItemCount, pastVisibleItems, totalItemCount);
}
}
};
handler.postDelayed(checkForMoreData, 100);
}
private void onScrollToLoad(int visibleItemCount, int pastVisibleItems, int totalItemCount) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount && hasMoreRequest) {
if (BuildConfig.DEBUG)
Log.d(TAG, "onScroll lastInScreen - so load more");
startApi(page + 1);
}
}
每当滚动到达滚动底部时,此代码将为下一页调用 API。
同样在每个 API 之后,我再次调用 checkForMoreLoad()
方法来检查是否需要更多数据。是的,不要忘记在向适配器
添加新元素后添加 adapter.notifyItemRangeChanged()
参考this。它在这里以一种很酷的方式解释。
基本上你需要一个 onScrollChangeListener
来检测你的 recyclerview 中的滚动变化,但仅此一点是无济于事的。因此,您需要一种方法来检查您当前是否到达回收站视图的底部。所以这是你如何做的:
检查上面的这一行link
// 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);
}
查看变量 visibleThreshold,您可以在其中修改并应用您自己的自定义值来进行第二次调用。
让我们检查值:
如果 visibleThreshold
为 0,并且您的列表中有 10 个项目,您在第 6 个项目上,第一个项目是第 0 个项目:
这一行
if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount )
解释为 -> if (true && (0+6+0)>=10) 解释为 false!
因此现在不会进行第二次调用。当你的 lastitem 是第 10 项时(因为你的阈值是 0),它将被制作
但是现在如果你添加一个阈值 4,下一次调用将在满足现在的条件时进行:
解释为 -> if (true && (0+6+4)>=10) 解释为 true!
总而言之,visibleThreshold 是您添加逻辑的地方,其余的您可以从 link!
中实现样板代码
我正在创建一个新的 android 应用程序,我几乎完成了第一个屏幕。但是,当我到达屏幕底部时,应用程序并没有加载新数据,而是将我直接带到了页面的开头。
我正在使用的API会在我发送第二页请求时发送下一页。你能告诉我如何让应用程序在用户到达第一页末尾之前自动发送第二页请求吗?
我正在使用 volley 库以及 recyclerView 和 cardView。能否请您解释清楚我应该在哪里进行更改,我是应用程序开发的新手。
这里是截击请求:
private void discoverMovies() {
final ProgressDialog progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Fetching Data From DB");
progressDialog.show();
//Requesting the data.....
StringRequest stringRequest = new StringRequest(Request.Method.GET, tempURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
progressDialog.dismiss();
JSONObject parentObject = new JSONObject(response);
JSONArray parentArray = parentObject.getJSONArray("results");
for (int i = 0; i < parentArray.length(); i++) {
JSONObject object = parentArray.getJSONObject(i);
movieModel model = new movieModel(
object.getString("title"),
object.getString("overview"),
object.getString("release_date"),
object.getString("poster_path"),
object.getInt("id"),
object.getBoolean("adult"),
object.getInt("vote_count"),
object.getDouble("vote_average"),
object.getString("original_language"),
object.getString("backdrop_path")
);
movieModels.add(model);
adapter = new cardViewAdapter(getContext(), movieModels);
recyclerView.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(stringRequest);
}
对于分页,我使用以下代码
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (hasMoreRequest) {
if (dy > 0) { //check for scroll down
checkForMoreLoad();
}
}
}
});
private void checkForMoreLoad() {
final Handler handler = new Handler();
Runnable checkForMoreData = new Runnable() {
@Override
public void run() {
if (null != recyclerView) {
int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
int pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
onScrollToLoad(visibleItemCount, pastVisibleItems, totalItemCount);
}
}
};
handler.postDelayed(checkForMoreData, 100);
}
private void onScrollToLoad(int visibleItemCount, int pastVisibleItems, int totalItemCount) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount && hasMoreRequest) {
if (BuildConfig.DEBUG)
Log.d(TAG, "onScroll lastInScreen - so load more");
startApi(page + 1);
}
}
每当滚动到达滚动底部时,此代码将为下一页调用 API。
同样在每个 API 之后,我再次调用 checkForMoreLoad()
方法来检查是否需要更多数据。是的,不要忘记在向适配器
adapter.notifyItemRangeChanged()
参考this。它在这里以一种很酷的方式解释。
基本上你需要一个 onScrollChangeListener
来检测你的 recyclerview 中的滚动变化,但仅此一点是无济于事的。因此,您需要一种方法来检查您当前是否到达回收站视图的底部。所以这是你如何做的:
检查上面的这一行link
// 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);
}
查看变量 visibleThreshold,您可以在其中修改并应用您自己的自定义值来进行第二次调用。
让我们检查值:
如果 visibleThreshold
为 0,并且您的列表中有 10 个项目,您在第 6 个项目上,第一个项目是第 0 个项目:
这一行
if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount )
解释为 -> if (true && (0+6+0)>=10) 解释为 false!
因此现在不会进行第二次调用。当你的 lastitem 是第 10 项时(因为你的阈值是 0),它将被制作
但是现在如果你添加一个阈值 4,下一次调用将在满足现在的条件时进行: 解释为 -> if (true && (0+6+4)>=10) 解释为 true!
总而言之,visibleThreshold 是您添加逻辑的地方,其余的您可以从 link!
中实现样板代码