I have a list view which uses a base adapter, this is how I initialise it:
if (mBuses.size() < 1) {
// Initialising and loading data into adapter
mBuses = buses;
mBusesAdapter = new BusesArrayAdapter(BusesActivity.this, mBuses);
mBusesView.setAdapter(mBusesAdapter);
} else {
mBuses.addAll(buses);
mBusesAdapter.notifyDataSetChanged();
}
I am using a listener to check when the user scrolls to the bottom it fetches more data from the server the server and appends to the existing set instead of using pagination. It loads 100 items per page.
Now my problem is when I try to filter the data it always only filters the first 100 items, it does not include the other items.
This is my base adapter:
public class BusesArrayAdapter extends BaseAdapter implements Filterable {
private Context context;
private int altColour;
private ArrayList<BusModel> buses;
private BusModel bus;
private ValueFilter valueFilter;
private ArrayList<BusModel> filterList;
private static class ViewHolder{
RelativeLayout container;
TextView id;
TextView busType;
TextView registrationNo;
TextView vehicleModel;
TextView driverName;
TextView driverContact;
ImageButton btnEdit;
ImageButton btnRemove;
}
public BusesArrayAdapter(@NonNull Context context, @NonNull ArrayList<BusModel> buses) {
this.context = context;
this.buses = buses;
this.filterList = new ArrayList<>(buses);
}
@Override
public int getCount() {
return buses.size();
}
@Override
public BusModel getItem(int position) {
return buses.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
public void remove(BusModel bus) {
buses.remove(bus);
}
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
bus = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
final ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.row_buses, parent, false);
viewHolder.container = (RelativeLayout) convertView.findViewById(R.id.row_buses_ll_container);
viewHolder.id = (TextView) convertView.findViewById(R.id.row_buses_tv_id);
viewHolder.busType = (TextView) convertView.findViewById(R.id.row_buses_tv_bus_type);
viewHolder.registrationNo = (TextView) convertView.findViewById(R.id.row_buses_tv_registration_no);
viewHolder.vehicleModel = (TextView) convertView.findViewById(R.id.row_buses_tv_vehicle_model);
viewHolder.driverName = (TextView) convertView.findViewById(R.id.row_buses_tv_driver_name);
viewHolder.driverContact = (TextView) convertView.findViewById(R.id.row_buses_tv_driver_contact);
viewHolder.btnEdit = (ImageButton) convertView.findViewById(R.id.row_buses_btn_edit);
viewHolder.btnEdit.setTag(position);
viewHolder.btnRemove = (ImageButton) convertView.findViewById(R.id.row_buses_btn_trash);
viewHolder.btnRemove.setTag(position);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data from the data object via the viewHolder object
// into the template view.
if (altColour == 0) {
viewHolder.container.setBackgroundColor(Color.parseColor("#FFFFFF"));
altColour = 1;
} else {
viewHolder.container.setBackgroundColor(Color.parseColor("#EFEFEF"));
altColour = 0;
}
viewHolder.id.setText(String.valueOf(bus.getId()));
viewHolder.busType.setText(bus.getBusType());
viewHolder.registrationNo.setText(bus.getRegistrationNo());
viewHolder.vehicleModel.setText(bus.getVehicleModel());
viewHolder.driverName.setText(bus.getDriverName());
viewHolder.driverContact.setText(bus.getDriverContact());
viewHolder.btnEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = Integer.parseInt(viewHolder.btnRemove.getTag().toString());
BusModel bus = getItem(position);
if (bus != null) {
Intent editBusIntent = new Intent(context, EditBusActivity.class);
editBusIntent.putExtra("bus", bus);
((Activity) context).startActivityForResult(editBusIntent, 200);
}
}
});
viewHolder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = Integer.parseInt(viewHolder.btnRemove.getTag().toString());
removeBus(position);
}
});
// Return the completed view to render on screen
return convertView;
}
private void removeBus(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Confirm");
builder.setMessage("Are you sure you want to delete this item?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
BusesRequest busesRequest = new BusesRequest(context);
busesRequest.remove(getItem(position).getId(), mTrashOnSuccessListener, mTrashOnErrorListener);
remove(getItem(position));
notifyDataSetChanged();
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private Response.Listener<JSONObject> mTrashOnSuccessListener = new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
//
}
};
Response.ErrorListener mTrashOnErrorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Utils.showNetworkResponse(context, error);
}
};
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null && constraint.length() > 0){
ArrayList<BusModel> filterList = new ArrayList<BusModel>();
for(int i = 0; i < BusesArrayAdapter.this.filterList.size(); i++)
{
BusModel bus = BusesArrayAdapter.this.filterList.get(i);
if((bus.getRegistrationNo().toLowerCase())
.contains(constraint.toString().toLowerCase())
|| (bus.getDriverName().toLowerCase())
.contains(constraint.toString().toLowerCase()) ) {
filterList.add(new BusModel(
bus.getId(),
bus.getBusType(),
bus.getRegistrationNo(),
bus.getVehicleModel(),
bus.getDriverName(),
bus.getDriverContact()
));
}
}
results.count = filterList.size();
results.values = filterList;
} else{
results.count = filterList.size();
results.values = filterList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
buses = (ArrayList<BusModel>) results.values;
notifyDataSetChanged();
}
}
}
because filterList
init only once while you are creating an instance of Adapter. you have to put new 100 items in filterList
also.
this.filterList = new ArrayList<>(buses);
stores only 100 records when you are creating a new instance like this.
mBusesAdapter = new BusesArrayAdapter(BusesActivity.this, mBuses);
try to add every fetched items filterList
also.