Reputation: 953
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)
2) 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!
Upvotes: 3
Views: 1458
Reputation: 303
For those who would be struggling in this issue in the future you can simply assign the number of entries to an Integer (in my below case its numb) and then before running the Async background function to load more results in the list view is to make sure the number of entries appears in the listview is less than the query entries. If not, you can run the Async task again to append more results.
L3.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = L3.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (L3.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
// Toast.makeText(getApplicationContext(), count- threshold+"", 300).show();
if(L3.getLastVisiblePosition()+ threshold <numb)
{
//Toast.makeText(getApplicationContext(), L3.getLastVisiblePosition()+"", 300).show();
new LoadMoreDataTask().execute();
}
else
{
Toast.makeText(getApplicationContext(), "لا توجد مزيد من النتائج حاليآ...", 300).show();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
Hope it helps!!
Upvotes: 0
Reputation: 13223
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.
Upvotes: 1