【发布时间】:2016-03-22 14:17:20
【问题描述】:
我对 android 开发非常陌生,我知道这个问题之前可能已经回答过了,但我似乎找不到适合我情况的答案。我正在创建一个具有ListView 以显示项目列表的android 应用程序。当用户到达ListView 的页脚时,我需要显示更多项目(比如 10 个更多项目)。我已经实现了setOnScrollListener()。我唯一需要您指导的问题是,当用户到达ListView 的底部时,我怎样才能获得更多物品。我应该为它创建另一个AsyncTask 吗?如果是,那么我怎么能做到这一点...我目前正在展示 10 个项目,并且我正在使用 AsyncTask 以 JSON 格式的 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();
}
我真的被这个问题困住了......有人可以帮我解决这个问题......我会很感激你。
我还创建了一个自定义适配器 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;
}
}
提前致谢
【问题讨论】:
-
你需要再次调用你的异步任务,当响应到来时,你需要添加你提供给适配器的同一个列表,并且需要在适配器对象上调用 notifydatasetchange。您也可以使用第三方列表,github.com/codepath/android_guides/wiki/…
-
我试图调用我当前的 AsyncTask 但它在列表视图中显示的结果与以前相同
-
已经在做
mRecipeAdapter.notifyDataSetChanged();可能做错了吗? -
请检查您是否从 api 获取新数据,假设在我的 api 中我有 page_limit,所以滚动时我将传递 page_limit=10,因此 api 返回第 10 页数据。所以你还需要检查你的 api 是返回相同的数据还是不同的数据。
-
API 正在显示 10 个最近的项目...我的意思是新添加的项目在顶部 .. 所以首先 api 将显示最新的项目 .. 如果我添加一个新项目,那么最后一个项目(第 10 项会消失)你认为这可能是因为 API 的原因吗?
标签: android listview android-asynctask