如何使用AsyncTask或任何其他方法

时间:2016-03-22 14:17:21

标签: android listview android-asynctask

我对Android开发很新,我知道这个问题可能之前已经回答,但我似乎无法找到适合我情况的答案。我正在创建一个Android应用程序,其中ListView显示项目列表。当用户到达ListView的页脚时,我需要显示更多项目(比如10个项目)。我已经实现了setOnScrollListener()。我唯一需要你指导的问题是,当用户到达ListView的底部时,如何获得更多项目。我应该为它创建另一个AsyncTask吗?如果是,那我该如何解决这个问题...我目前正在展示10个项目,我正在使用JSONAsyncTask格式通过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;
    }

}

提前致谢

2 个答案:

答案 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);
            }
        }
    }