我对Android开发很新,我知道这个问题可能之前已经回答,但我似乎无法找到适合我情况的答案。我正在创建一个Android应用程序,其中ListView
显示项目列表。当用户到达ListView
的页脚时,我需要显示更多项目(比如10个项目)。我已经实现了setOnScrollListener()
。我唯一需要你指导的问题是,当用户到达ListView
的底部时,如何获得更多项目。我应该为它创建另一个AsyncTask
吗?如果是,那我该如何解决这个问题...我目前正在展示10个项目,我正在使用JSON
以AsyncTask
格式通过API获取这些项目。以下是AsyncTask
的代码。
public class GetRecipeData extends AsyncTask<Object, Void, JSONObject> {
public final int NUMBER_OF_POSTS = 10;
int responseCode = -1;
JSONObject recipeJsonResponse = null;
@Override
protected JSONObject doInBackground(Object... params) {
try {
URL blogFeedUrl = new URL("http://www.bestfoodrecipesever.com/api/get_category_posts/?slug="+RECIPE_CAT+"&count="+NUMBER_OF_POSTS);
HttpURLConnection connection = (HttpURLConnection) blogFeedUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK){
InputStream inputStream = connection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
String recipeDataJsonStr = buffer.toString();
recipeJsonResponse = new JSONObject(recipeDataJsonStr);
}else {
Log.i(LOG_TAG, "Unsuccessful HTTP Response Code: " + responseCode);
}
}
catch (MalformedURLException e){
Log.e(LOG_TAG,"Exception Caught: ",e);
}
catch (IOException e) {
Log.e(LOG_TAG, "IO Exception Caught: ",e);
}
catch (Exception e) {
Log.e(LOG_TAG,"Exception Caught: ",e);
}
return recipeJsonResponse;
}
@Override
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
mRecipeData = result;
handleRecipeData();
}
}
以下是handleRecipeData()
方法的代码:
private void handleRecipeData() {
mProgressBar.setVisibility(View.INVISIBLE);
if(mRecipeData == null){
handleErrors();
}else {
try {
getRecipeData();
} catch (JSONException e) {
Log.e(LOG_TAG,"Exception Caught: ",e);
}
}
}
以下是getRecipeData()
方法中使用的handleRecipeData()
方法的代码:
private void getRecipeData() throws JSONException {
JSONArray jsonPosts = mRecipeData.getJSONArray("posts");
mRecipePostData = new ArrayList<>();
for (int i = 0; i < jsonPosts.length(); i++){
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String author = post.getJSONObject(KEY_AUTHOR).getString("name");
author = Html.fromHtml(author).toString();
String imgUrl = post.getJSONObject(KEY_IMG_URL).getJSONObject("full").getString("url");
String recipeContent = post.getString(KEY_CONTENT);
recipeContent = Html.fromHtml(recipeContent).toString();
String recipeUrl = post.getString(KEY_RECIPE_URL);
HashMap<String, String> singleRecipePost = new HashMap<>();
singleRecipePost.put(KEY_TITLE, title);
singleRecipePost.put(KEY_AUTHOR, author);
singleRecipePost.put(KEY_IMG_URL, imgUrl);
singleRecipePost.put(KEY_CONTENT, recipeContent);
singleRecipePost.put(KEY_RECIPE_URL, recipeUrl);
mRecipePostData.add(singleRecipePost);
}
String[] keys = {KEY_TITLE};
int[] ids = {R.id.list_recipe_title};
mRecipeAdapter = new ExtendedSimpleAdapter(getContext(), mRecipePostData, R.layout.itemlistrow, keys, ids);
listView.setAdapter(mRecipeAdapter);
mRecipeAdapter.notifyDataSetChanged();
}
我真的被这个问题困住了......有人可以帮我解决这个问题......我会很高兴你。
我还创建了一个自定义Adapter ExtendedSimpleAdapter。这是此适配器的代码。如果有人想要查看它:
public class ExtendedSimpleAdapter extends SimpleAdapter {
Context context2;
public ExtendedSimpleAdapter(Context context, List<? extends Map<String, String>> data, int resource, String[] from, int[] to){
super(context, data, resource, from, to);
context2=context;
}
public View getView(int position, View convertView, ViewGroup parent){
// here you let SimpleAdapter built the view normally.
View v = super.getView(position, convertView, parent);
// Then we get reference for Picasso
//TextView recipeTitle = (TextView) v.getTag();
ImageView recipeThumb = (ImageView) v.getTag();
if(recipeThumb == null){
//recipeTitle = (TextView) v.findViewById(R.id.list_recipe_title);
recipeThumb = (ImageView) v.findViewById(R.id.list_recipe_thumb);
//v.setTag(recipeTitle);
v.setTag(recipeThumb); // <<< THIS LINE !!!!
}
// get the url from the data you passed to the `Map`
String TAG_IMAGE = "thumbnail_images";
String url = ((Map<String,String>) getItem(position)).get(TAG_IMAGE);
// do Picasso
// maybe you could do that by using many ways to start
Picasso.with(context2).load(url).resize(300, 200).centerCrop().into(recipeThumb);
// return the view
return v;
}
}
提前致谢
答案 0 :(得分:1)
每次调用数据时,都不会在每次显示新数据时设置适配器。只需将其设置为第一次,然后仅在从JSON收到新数据时通知适配器。
或者您可以使用其他列表存储新数据并将此列表添加到主列表 -
yourMainList.addAll(anotherList);
adapter.notifyDataSetChanged();
<强>更新 - 强>
1 - 取一个布尔值来检查列表是否滚动 boolean iScrolling = false 并在 onScroll中将其设为 true ()强> -
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem+visibleItemCount == totalItemCount && totalItemCount!=0) {
isScrolling = true;
mFooter.setVisibility(View.VISIBLE);
/*GetRecipeData getRecipeData = new GetRecipeData();
getRecipeData.execute();*/
GetRecipeData getRecipeData = new GetRecipeData();
getRecipeData.execute(yourCounts); // update
}
}
});
现在 getRecipeData() -
中的一些变化 private void getRecipeData() throws JSONException {
JSONArray jsonPosts = mRecipeData.getJSONArray("posts");
mRecipePostData = new ArrayList<>();
for (int i = 0; i < jsonPosts.length(); i++){
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String author = post.getJSONObject(KEY_AUTHOR).getString("name");
author = Html.fromHtml(author).toString();
String imgUrl = post.getJSONObject(KEY_IMG_URL).getJSONObject("full").getString("url");
String recipeContent = post.getString(KEY_CONTENT);
recipeContent = Html.fromHtml(recipeContent).toString();
String recipeUrl = post.getString(KEY_RECIPE_URL);
HashMap<String, String> singleRecipePost = new HashMap<>();
singleRecipePost.put(KEY_TITLE, title);
singleRecipePost.put(KEY_AUTHOR, author);
singleRecipePost.put(KEY_IMG_URL, imgUrl);
singleRecipePost.put(KEY_CONTENT, recipeContent);
singleRecipePost.put(KEY_RECIPE_URL, recipeUrl);
mRecipePostData.add(singleRecipePost);
}
String[] keys = {KEY_TITLE};
int[] ids = {R.id.list_recipe_title};
if (!isScrolling){
mRecipeAdapter = new ExtendedSimpleAdapter(getContext(), mRecipePostData, R.layout.itemlistrow, keys, ids);
listView.setAdapter(mRecipeAdapter);
mRecipeAdapter.notifyDataSetChanged();
}else{
mRecipeAdapter.notifyDataSetChanged();
isScrolling = false;
}
}
2 - 或者您可以在其他列表的帮助下完成 - 拿另一个列表并在其上添加数据并将此列表添加到主列表中,在 getRecipeData() -
中 private void getRecipeData() throws JSONException {
JSONArray jsonPosts = mRecipeData.getJSONArray("posts");
if (!isScrolling) {
mRecipePostData = new ArrayList<>();
}else{
yourSecondList = new ArrayList<>();
}
for (int i = 0; i < jsonPosts.length(); i++){
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String author = post.getJSONObject(KEY_AUTHOR).getString("name");
author = Html.fromHtml(author).toString();
String imgUrl = post.getJSONObject(KEY_IMG_URL).getJSONObject("full").getString("url");
String recipeContent = post.getString(KEY_CONTENT);
recipeContent = Html.fromHtml(recipeContent).toString();
String recipeUrl = post.getString(KEY_RECIPE_URL);
HashMap<String, String> singleRecipePost = new HashMap<>();
singleRecipePost.put(KEY_TITLE, title);
singleRecipePost.put(KEY_AUTHOR, author);
singleRecipePost.put(KEY_IMG_URL, imgUrl);
singleRecipePost.put(KEY_CONTENT, recipeContent);
singleRecipePost.put(KEY_RECIPE_URL, recipeUrl);
if (!isScrolling) {
mRecipePostData.add(singleRecipePost);
}else{
yourSecondList.add(singleRecipePost);
}
}
String[] keys = {KEY_TITLE};
int[] ids = {R.id.list_recipe_title};
if (!isScrolling){
mRecipeAdapter = new ExtendedSimpleAdapter(getContext(), mRecipePostData, R.layout.itemlistrow, keys, ids);
listView.setAdapter(mRecipeAdapter);
mRecipeAdapter.notifyDataSetChanged();
}else{
mRecipePostData.addAll(yourSecondList);
mRecipeAdapter.notifyDataSetChanged();
isScrolling = false;
}
}
<强>更新 - 强>
更改AsyncTask参数 -
public class GetRecipeData extends AsyncTask<String, Void, JSONObject> {
// your code..
@Override
protected JSONObject doInBackground(String... params) {
try {
URL blogFeedUrl = new URL("http://www.bestfoodrecipesever.com/api/get_category_posts/?slug=" + RECIPE_CAT + "&count=" + params[0]);
// your code...
}
}
}
并在此处进行一些更改 -
if(isNetworkAvailable()) {
mProgressBar.setVisibility(View.VISIBLE);
GetRecipeData getRecipeData = new GetRecipeData();
getRecipeData.execute(yourCount);
} else {
Toast.makeText(getContext(),getString(R.string.no_network), Toast.LENGTH_LONG).show();
}
希望它会有所帮助。
答案 1 :(得分:0)
尝试这样:
//used for populate the listView
private void populateListView(HashMap<String, String> datas){
if(mRecipeAdapter ==null){
String[] keys = {KEY_TITLE};
int[] ids = {R.id.list_recipe_title};
mRecipeAdapter = new ExtendedSimpleAdapter(getContext(), datas, R.layout.itemlistrow, keys, ids);
listView.setAdapter(mRecipeAdapter);
}else
{
mRecipeAdapter.notifyDataSetChanged();
}
}
//create ListView Data::: i have removed your five last line, and repleced them by return mRecipePostData
private ArrayList<HashMap<String,String>> getRecipeData() throws JSONException {
JSONArray jsonPosts = mRecipeData.getJSONArray("posts");
mRecipePostData = new ArrayList<HashMap<String,String>>();
for (int i = 0; i < jsonPosts.length(); i++){
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String author = post.getJSONObject(KEY_AUTHOR).getString("name");
author = Html.fromHtml(author).toString();
String imgUrl = post.getJSONObject(KEY_IMG_URL).getJSONObject("full").getString("url");
String recipeContent = post.getString(KEY_CONTENT);
recipeContent = Html.fromHtml(recipeContent).toString();
String recipeUrl = post.getString(KEY_RECIPE_URL);
HashMap<String, String> singleRecipePost = new HashMap<>();
singleRecipePost.put(KEY_TITLE, title);
singleRecipePost.put(KEY_AUTHOR, author);
singleRecipePost.put(KEY_IMG_URL, imgUrl);
singleRecipePost.put(KEY_CONTENT, recipeContent);
singleRecipePost.put(KEY_RECIPE_URL, recipeUrl);
mRecipePostData.add(singleRecipePost);
}
return mRecipePostData;
}
//after getData, i am populating ListView
private void handleRecipeData() {
mProgressBar.setVisibility(View.INVISIBLE);
if(mRecipeData == null){
handleErrors();
}else {
try {
HashMap<String, String> datas=getRecipeData();
populateListView(datas);
} catch (JSONException e) {
Log.e(LOG_TAG,"Exception Caught: ",e);
}
}
}