向下滚动后更新数据后,GridView为空白

时间:2016-08-04 13:57:34

标签: android android-gridview android-json

我是使用TMDb API来构建项目应用程序。每次api通话都会给我20部电影,所以通常应用程序在启动时只显示20部电影海报。当用户向下滚动网格视图时,我添加了此代码以使用& page =查询获取另外20部电影。

gridView.setOnScrollListener(onScrollListener());

private AbsListView.OnScrollListener onScrollListener() {
        return new AbsListView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                int threshold = 1;
                int count = gridView.getCount();

                if (scrollState == SCROLL_STATE_IDLE) {
                    if (gridView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
                        Log.v(LOG_TAG, "loading more data");
                        // Execute LoadMoreDataTask AsyncTask
                        updateMovies(sortBy, true);
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                                 int totalItemCount) {
            }

        };
    }

但是这个解决方案非常糟糕。如果我向下滚动它会立即执行updateMovies(sortBy, true); 2-3次,跳页并使其无法读取。

此外,屏幕上显示的数据在每次刷新页面后都会被完全替换,例如,如果我在页面上看到数据= 1并向下滚动,那么我只看到第2页或第3页的数据,但原始数据是走了。

这是我的AsyncTask

public class FetchMoviesTask extends AsyncTask<String, Void, List<Movie>> {

        private final String LOG_TAG = FetchMoviesTask.class.getSimpleName();
        private final static String API_KEY = "480a9e79c0937c9f4e4a129fd0463f96";



        @Override
        protected List<Movie> doInBackground(String... params) {

            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;
            String jsonStr = null;
            try {
                final String BASE_URL = "http://api.themoviedb.org/3/movie";
                final String API_KEY_PARAM = "api_key";
                final String PAGE_PARAM = "page";
                URL url;
                if (params[1].equals("true")){
                    // if a bool is true
                    // then I intend to load an additional page
                    // (needed otherwise going back from detailAct loads a new increasing page
                    currentPage += 1;
                    pageCount++;
                }else{
                    currentPage = 1;
                }


                if (params[0].equals(POPULARITY_DESC)){
                    Uri builtUri = Uri.parse(BASE_URL).buildUpon()
                            .appendPath("popular")
                            .appendQueryParameter(API_KEY_PARAM, API_KEY)  // my own API key
                            .appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
                            .build();
                    url = new URL(builtUri.toString());

                }else if(params[0].equals(RATING_DESC)) {
                    Uri builtUri = Uri.parse(BASE_URL).buildUpon()
                            .appendPath("top_rated")
                            .appendQueryParameter(API_KEY_PARAM, API_KEY)// my own API key
                            .appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
                            .build();
                    url = new URL(builtUri.toString());

                }else {
                    Log.v(LOG_TAG, "Something went wrong with URI building :(");
                    url = new URL("ERROR URL");
                }



                Log.v(LOG_TAG, "URL BUILT: " + url);

                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                if (inputStream == null) {
                    return null;
                }
                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) {
                    return null;
                }
                jsonStr = buffer.toString(); // finally parsed JSON string
            } catch (IOException e) {
                Log.e(LOG_TAG, "Error ", e);
                return null;
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (final IOException e) {
                        Log.e(LOG_TAG, "Error closing stream", e);
                    }
                }
            }

            try {
                return getMoviesDataFromJson(jsonStr);
            } catch (JSONException e) {
                Log.e(LOG_TAG, e.getMessage(), e);
                e.printStackTrace();
            }

            // This will only happen if there was an error getting or parsing the forecast.
            return null;
        }

        private List<Movie> getMoviesDataFromJson(String jsonStr) throws JSONException {
            JSONObject movieJson = new JSONObject(jsonStr);
            JSONArray movieArray = movieJson.getJSONArray("results");

            List<Movie> results = new ArrayList<>();

            for(int i = 0; i < movieArray.length(); i++) {
                JSONObject movie = movieArray.getJSONObject(i);
                Movie movieModel = new Movie(movie); // basically Movie has already the fields to fill (image,
                // description, rating, etc) and this adds those values from the JSONObject
                results.add(movieModel); // it does this one object at the time, for the lenght of the array
            }

            return results;
        }


        @Override
        protected void onPostExecute(List<Movie> mv) {
            if (mv != null) {
                if (movieGridAdapter != null) {
                    movieGridAdapter.clear();
                    for (Movie movie : mv) {
                        movieGridAdapter.add(movie);
                    }
                }
                movies = new ArrayList<>();
                movies.addAll(mv);
            }
        }


    }

0 个答案:

没有答案