Question

Anyone can pinpoint whats the problem in my code.

My AutoCompleteTextView has strange behavior when I press the backspace. At first when I type on the Textbox it will show the correct values. For example I have a list of string namely "Pallanos", "Palana", "Pandor", "Pasdi".

When i type Pal then Pallanos and Palana will show. But when I press the backspace the suggestion dropbox was NOT refresh. I should have a result of four namely the string above.

Heres my Adapter

class EmployeeAdapter extends ArrayAdapter<EmployeeDetails>{

Context context; 
int layoutResourceId;
ArrayList<EmployeeDetails> data;
ArrayList<EmployeeDetails> objects;
//EmployeeDetails data[] = null;

public EmployeeAdapter(Context c, int paramlayoutResourceId, ArrayList<EmployeeDetails> collection) { //EmployeeDetails[] collection) {
    super(c, paramlayoutResourceId, collection);
    this.layoutResourceId = paramlayoutResourceId;
    this.context = c;
    this.data = collection;
    this.objects = collection;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    if(row == null) {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, null);
    }

    EmployeeDetails emp = data.get(position);
    Departments dept = new Departments(context);
    AccountTypes accType = new AccountTypes(context);

    ((TextView) row.findViewById(R.id.tvMainHeader)).setText(emp.getFirstName() + ", " + emp.getLastName());
    ((TextView) row.findViewById(R.id.tvSubHeader)).setText(dept.GetDepartmentName(emp.getDepartmentID()).toString() + " - " + accType.GetAccountTypeName(emp.getAccountTypeID()).toString());
    ((ImageView) row.findViewById(R.id.imgHeader)).setImageResource(R.drawable.id_card);

    return row;
}

@Override
public Filter getFilter() {
    //return nameFilter;

    Filter nameFilter = new Filter() {

        public String convertResultToString(Object resultValue) {
            String str = ((EmployeeDetails)(resultValue)).getLastName();
            return str;
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<EmployeeDetails> suggestions = new ArrayList<EmployeeDetails>();
            FilterResults filterresults = new FilterResults();

            if (constraint != null) {
                suggestions.clear();

                for (EmployeeDetails employee : objects) {
                    if (employee.getLastName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                        suggestions.add(employee);
                    }
                }

                filterresults.values = suggestions;
                filterresults.count = suggestions.size();
            }

            return filterresults; 
        }

        @Override
        @SuppressWarnings("unchecked")
        protected void publishResults(CharSequence constraint, FilterResults results) {
            ArrayList<EmployeeDetails> filteredList = (ArrayList<EmployeeDetails>) results.values;

            if (filteredList != null && filteredList.size() > 0) {
                clear();
                for (EmployeeDetails employee : filteredList) {
                    add(employee);
                }
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    };

    return nameFilter;
} 
}

Below code show on how I use the adapter in my AutoCompleteTextView

    EmployeeAdapter adapter = new EmployeeAdapter(this, R.layout.list_row, empFunction.GetAllEmployees());

    AutoCompleteTextView empAuto = (AutoCompleteTextView)findViewById(R.id.auto_Employee);
    empAuto.setThreshold(1);
    empAuto.setAdapter(adapter);
Was it helpful?

Solution

I found my solution on my problem. But its a little bit slow. If someone can optimize then feel free to post your answer. :)

Instead of equating object (this.objects = collection) variable inside my constructor I place it inside performFiltering. The idea was to refresh the objects variable every time performFiltering method fire.

Some people add TextWatcher in the TextView to refresh their adapter.

Below is my modified perFormFiltering

            protected FilterResults performFiltering(CharSequence constraint) {
            EmployeeDetails empFunction = new EmployeeDetails(context);
            ArrayList<EmployeeDetails> suggestions = new ArrayList<EmployeeDetails>();
            FilterResults filterresults = new FilterResults();

            if (constraint != null) {
                suggestions.clear();
                objects = empFunction.GetAllEmployees();
                for (EmployeeDetails employee : objects) {
                    if (employee.getLastName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                        suggestions.add(employee);
                    }
                }

                filterresults.values = suggestions;
                filterresults.count = suggestions.size();
            }

            return filterresults; 
        }

Thanks

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top