如何使用AsyncTask或任何其他方法在ListView中加载更多项目 [英] How to load more items in a ListView using AsyncTask or any other method

查看:62
本文介绍了如何使用AsyncTask或任何其他方法在ListView中加载更多项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对android开发非常陌生,我知道这个问题以前可能是答案,但是我似乎找不到适合我情况的合适答案.我正在创建一个具有ListView的Android应用程序以显示项目列表.当用户到达ListView的页脚时,我需要显示更多项(例如10项).我已经实现了setOnScrollListener().我唯一需要解决的问题是,当用户到达ListView的底部时,如何获得更多物品.我应该为此创建另一个AsyncTask吗?如果是,那么我该如何实现……我目前正在显示10个项目,并且正在使用AsyncTask通过JSON格式的API获取这些项目.以下是该AsyncTask的代码.

I am very new to android development and I know that this question might be answer before but I can't seem to find a suitable answer for my situation. I am creating an android app which have a ListView to show list of items. I need to show more items (like 10 more items) when the user reaches the footer of the ListView. I have implemented the setOnScrollListener(). My only issue and for which I need your guidance is that how can I get more items when the user reaches the bottom of the ListView. Should I create another AsyncTask for it? If yes then how can I ahieve this ... I am currently showing 10 items and I am getting those items through an API in JSON format using an AsyncTask. Below is the code for that 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);
            }
        }
    }

这是handleRecipeData()方法中正在使用的getRecipeData()方法的代码:

And Here is the code for the getRecipeData() Method which is being used within the handleRecipeData() Method:

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();
    }

我真的很困扰这个问题...有人可以帮我解决这个问题...我将对您很满意.

I am really stuck with this issue ... Can somebody help me out with this ... I would be greatful to you.

我还创建了一个自定义适配器ExtendedSimpleAdapter.这是此适配器的代码.如果有人想对其进行审查:

I also created a custom Adapter ExtendedSimpleAdapter. Here is the code for this Adapter. In case someone might want to review it:

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;
    }

}

预先感谢

推荐答案

不要在每次调用数据时始终设置适配器以向您显示新数据.只需对其进行第一次设置,然后仅当您从JSON接收到新数据时才通知适配器.

Do not set adapter every time it will show you new data all the time when you will call for data. Just set it first time then only notify the adapter when you received new data from JSON.

或者您可以使用另一个列表来存储新数据,并将此列表添加到主列表中-

Or you can use another List to store new data and add this list to your main List -

 yourMainList.addAll(anotherList);
 adapter.notifyDataSetChanged();

更新-

1-取一个布尔值以检查列表是否滚动 boolean iScrolling = false 并使其在 onScroll中为 true ()-

1- Take a boolean value to check list is scrolling or not boolean iScrolling = false and make it true inside onScroll()-

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()-

2- Or you can do it with the help of another List- Take another List and add data on it and add this List to your main List, inside 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参数-

Change your AsyncTask params-

 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...
        }
    }
}

还要在此处进行一些更改-

And also make some change here-

 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();
    }

希望这会有所帮助.

这篇关于如何使用AsyncTask或任何其他方法在ListView中加载更多项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆