I'm using ListView
which is populated by custom adapter that extends BaseAdapter
. Data is fetched from external server with AsyncTask
and onPostExecute method of AsyncTask
calls a method on ListActivity
that sets adapter to display data
ListView
also implements OnScrollListener
to fetch data on scroll and add to bottom.
I've an ActionBar
(Toolbar
) with custom view which contains EditText
fields and Button
on click of which, again, same AsyncTask
is called to fetch new data with query values passed from Toolbar
.
Problem is, when button on toolbar is clicked I want the ListView
to be populated with entirely new data replacing the old values but instead new data is appended at the bottom of list ( as if OnClickListener
is called).
I checked Link1, Link2 but none seem to help
And of course main strike would be to use NotifyDataSetChange
and I'm using that too but not worth it.
My method to set adapter
public void setBusinesses(ArrayList<BusinessListData> businesses) {
imgFetcher = new BusinessListIconTask(this);
layoutInflator = LayoutInflater.from(this);
if (this.businesses == null || adapter == null) {
this.businesses = new ArrayList<>();
adapter = new BusinessListDataAdapter(this, imgFetcher,
layoutInflator, this.businesses);
businessList.setAdapter(adapter);
}
this.businesses.addAll(businesses);
adapter.notifyDataSetChanged();
/* Activates when scrolling to bottom of list */
businessList.setOnScrollListener(new OnScrollListener() {
public int currentScrollState;
public int currentFirstVisibleItem;
public int currentVisibleItemCount;
public int totalItemCount;
public int lastItem;
boolean isLoading = false;
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItemCount = totalItemCount;
this.lastItem = firstVisibleItem + visibleItemCount;
}
private void isScrollCompleted() {
if (this.lastItem == this.totalItemCount) {
/*** In this way I detect if there's been a scroll which has completed ***/
if (!isLoading) {
isLoading = true;
getScrollData(metroTxt, metroLoc, metroId);
}
} else {
businessList.removeFooterView(footerView);
}
}
});
}
setting custom toolbar with search fields
void showCustomView(String metroTxt, String metroLoc, String metroId) {
LayoutInflater mInflater = LayoutInflater.from(this);
if (mCustomView == null)
mCustomView = mInflater.inflate(R.layout.custom_action_bar, null);
mToolbar.removeView(mCustomView);
mToolbar.addView(mCustomView);
Log.d("I'm inside custom view", "txt" + metroTxt);
abKeyword = (CustomAutoCompleteTextView) mCustomView
.findViewById(R.id.ab_keyword);
abLocation = (CustomAutoCompleteTextView) mCustomView
.findViewById(R.id.ab_location);
ab_search = (Button) mCustomView
.findViewById(R.id.ab_search);
abKeyword.append(metroTxt);
abLocation.setVisibility(View.GONE);
ab_search.setVisibility(View.GONE);
abKeyword.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus || !abKeyword.getText().toString().isEmpty() || !abLocation.getText().toString().isEmpty()) {
abLocation.setVisibility(View.VISIBLE);
ab_search.setVisibility(View.VISIBLE);
} else {
abLocation.setVisibility(View.GONE);
ab_search.setVisibility(View.GONE);
}
}
});
abKeyword.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable editable) {
// TODO Auto-generated method stub
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
String newText = s.toString();
BusinessInfoSuggestionTask autocompleteTask = new BusinessInfoSuggestionTask(BusinessResultListActivity.this);
String acType = "keyword";
if (s.length() >= 1) {
abLocation.setVisibility(View.VISIBLE);
ab_search.setVisibility(View.VISIBLE);
autocompleteTask.execute(newText, acType, cActivity);
} else {
abLocation.setVisibility(View.GONE);
ab_search.setVisibility(View.GONE);
}
}
});
ab_search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
String abKey = abKeyword.getText().toString();
String abLoc = abLocation.getText().toString();
String abId = "";
getBusinesses(abKey, abLoc, abId);
Log.d("I'm clicked", "button on toolbar clicked");
}
});
}
Methods to fetch data from server
/* Get Businesses data from server */
private void getBusinesses(String metroTxt, String metroLoc, String metroId) {
// TODO Auto-generated method stub
String first = "first";
BusinessListApiTask spTask = new BusinessListApiTask(
BusinessResultListActivity.this);
try {
spTask.execute(metroTxt, metroLoc, metroId, first);
} catch (Exception e) {
spTask.cancel(true);
}
}
/* Fetch more data on scroll */
private void getScrollData(String metroTxt, String metroLoc, String metroId) {
// TODO Auto-generated method stub
String first = "next";
BusinessListApiTask spTask = new BusinessListApiTask(
BusinessResultListActivity.this);
try {
spTask.execute(metroTxt, metroLoc, metroId, first); //Call AsyncTask to fetch data from server
} catch (Exception e) {
spTask.cancel(true);
}
}
You are using .addAll()
which appends data to the data the adapter already has. The quick-fix is to just drop all data prior to calling .addAll()
by using .clear()
.
//...
this.businesses.clear();
this.businesses.addAll(businesses);
adapter.notifyDataSetChanged();
//...