Search code examples
javaandroidandroid-listviewparse-platformonscrolllistener

How to not load all ListView items again?


I am using Parse.com framework and i've recently added a load-more (onScroll) ListView to my code. But I found out that whenever the load-more process starts, even the previous items load again. When I add query.setSkip(someCustomSkip);, after the load-more process it just drops items without the number of (someCustomSkip) number.

Do you have any idea, how can I use query.setSkip(); method and also conserve the provious ones?

1) ListView's first position, before scrolling to 5th position query.setLimit(mListView.getCount + 5)

ListView's first position, before scrolling to 5th position (<code>query.setLimit(mListView.getCount + 5</code>)

2) ListView after scrolling to limit-position. It throws me to this position and sets skip - hides first 5 items

ListView after scrolling to limit-position. It throws me to this position and sets skip - hides first 5 items

And also part of my code, which is important for this question:

public class Fragment1 extends Fragment {
    static ListView mListView;
    static AnimalAdapter mAdapter;
    static ProgressBar mProgressBar;
    static EditText mEditText;
    static LayoutInflater inflater;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        final View rootView = inflater.inflate(R.layout.animalsfrag, container, false);
        mListView = (ListView)rootView.findViewById(R.id.animal_list);

        View header = getActivity().getLayoutInflater().inflate(R.layout.header, null);

        header.setPadding(2, 8, 4, 2);
        mListView.setVisibility(View.INVISIBLE);
        mListView.requestFocus();
        mListView.addHeaderView(header); 

        View footie = getActivity().getLayoutInflater().inflate(R.layout.footer, null);
        mListView.addFooterView(footie);
        footie.setVisibility(View.INVISIBLE);


        mProgressBar = (ProgressBar) rootView.findViewById (R.id.loading_animals);
        mProgressBar.setVisibility(View.VISIBLE);

        RemoteDataTask task = new RemoteDataTask();
        task.execute();



        return rootView;
    }



    public void updateData() { //method, which updates my data
         mListView = (ListView)getView().findViewById(R.id.animal_list);     
   final ParseQuery<Animal> query = ParseQuery.getQuery(Animal.class);


    query.setCachePolicy(CachePolicy.NETWORK_ONLY);
    query.orderByAscending("animal");


    query.setLimit(mListView.getCount() + 5);
    if (mListView.getCount() > 5) {
        query.setSkip(5);
    }

    query.findInBackground(new FindCallback<Animal>() {

        @Override
          public void done(List<Animal> animals, ParseException error) {

              if(animals != null){
                  mAdapter.clear();

                mProgressBar = (ProgressBar) getView().findViewById (R.id.loading_animals);
               mProgressBar.setVisibility(View.INVISIBLE);
             RelativeLayout footie = (RelativeLayout) getView().findViewById(R.id.footerview);  
            footie.setVisibility(View.VISIBLE);

            for (int i = 0; i < animals.size(); i++) {


                      mAdapter.add(animals.get(i));







                  }  
              }  
            }
         }); 
    } 




     private class RemoteDataTask extends AsyncTask<Void, Void, Void> {


         @Override
            protected void onPreExecute() {
                super.onPreExecute();  }

         @Override
            protected Void doInBackground(Void... params) {

                return null;



         }


         @Override
            protected void onPostExecute(Void result) {


               mListView = (ListView) getView().findViewById(R.id.animal_list);

               mEditText = (EditText) getView().findViewById(R.id.search_animal);

               mAdapter = new AnimalAdapter(getActivity(), new ArrayList<Animal>());

               mListView.setVisibility(View.VISIBLE);
               mListView.setTextFilterEnabled(true);
               mListView.setAdapter(mAdapter);




               mListView.setOnScrollListener(new OnScrollListener() { 
      //my OnScrollListener

                    @Override
                    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                            int totalItemCount) {
                        final int lastItem = firstVisibleItem + visibleItemCount;
                        if(lastItem == totalItemCount) {




                        if (mListView.getCount() > 20) {

                            RelativeLayout footie = (RelativeLayout) getView().findViewById(R.id.footerview);

                            mListView.removeFooterView(footie);

                              }





                            else{

                                updateData();


                            }

                        }

                    }


                    @Override
                    public void onScrollStateChanged(AbsListView view,
                            int scrollState) {

                        if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {
                            View currentFocus = getActivity().getCurrentFocus();
                            if(currentFocus != null) {
                                currentFocus.clearFocus();
                            }
                        }



                    }

                });
               mListView.setAdapter(mAdapter);

                mEditText.addTextChangedListener(new TextWatcher(){

                    @Override
                    public void afterTextChanged(Editable s) {}

                    @Override
                    public void beforeTextChanged(CharSequence s,
                            int start, int count, int after) {}

                    @Override
                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {

                        System.out.println("Text ["+s+"]");
                        mAdapter.getFilter().filter(s.toString());  
                        }
                });

               }

            }
         }

Thanks in advance for any suggestion!


Solution

  • I do not know if you are using it now, but Parse provides a class called ParseQueryAdapter that takes care of all of this. One of its constructors takes a Context and a QueryFactory. QueryFactory requires you to override create() and makes you return a ParseQuery.

    ParseQuery has an enum that describes its cache policy. If you do not want to ping the server every time, you can set the cache policy to check cache first and then hit the server if the ParseObject is not found in the local chache.

    Pagination is enabled by default on ParseQueryAdapter; it is all taken care for you (even the view that says "load more data".

    Here is a little code snippet from the docs that might help you:

    ParseQueryAdapter<ParseObject> adapter =
      new ParseQueryAdapter<ParseObject>(this, new ParseQueryAdapter.QueryFactory<ParseObject>() {
        public ParseQuery<ParseObject> create() {
          // Here we can configure a ParseQuery to our heart's desire.
          ParseQuery query = new ParseQuery("Band");
          query.whereContainedIn("genre", Arrays.asList({ "Punk", "Metal" }));
          query.whereGreaterThanOrEqualTo("memberCount", 4);
          query.orderByDescending("albumsSoldCount");
          query.setCachePolicy(ParseQuery.CachePolicy.CACHE_ELSE_NETWORK)
          return query;
        }
      });
    

    Then you just set the adapter in the ListView as you normally would.