Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create custom BaseAdapter for AutoCompleteTextView

I've been having difficulty creating a custom ArrayAdapter for AutoCompleteTextView such errors that would come up despite following code found on the internet would be:

  • Dropdown would not appear.
  • Custom Objects and their details would not appear.

So for those who are having or had the same problem as me, I recommend using BaseAdapter for AutoCompleteTextView instead.

like image 368
Hiroga Katageri Avatar asked Oct 09 '15 21:10

Hiroga Katageri


People also ask

How do I create an AutoCompleteTextView field in XML?

In android, we can create an AutoCompleteTextView control in two ways either manually in an XML file or create it in the Activity file programmatically. First we create a new project by following the below steps: Click on File, then New => New Project. After that include the Kotlin support and click on next.

How do I set autocomplete text on Android?

If you want to get suggestions , when you type in an editable text field , you can do this via AutoCompleteTextView. It provides suggestions automatically when the user is typing. The list of suggestions is displayed in a drop down menu from which the user can choose an item to replace the content of the edit box with.

What is the use of adapter object in Android SDK explain Arrayadapter in detail?

You can use this adapter to provide views for an AdapterView , Returns a view for each object in a collection of data objects you provide, and can be used with list-based user interface widgets such as ListView or Spinner .


1 Answers

The following is my working code using ArrayAdapter.

Let's assume the reponse data from web service looks like the following:

[
    {
        "id": "1",
        "name": "Information Technology"
    },
    {
        "id": "2",
        "name": "Human Resources"
    },
    {
        "id": "3",
        "name": "Marketing and PR"
    },
    {
        "id": "4",
        "name": "Research and Developement"
    }
]

Then in your Android client:

Department class:

public class Department {
    public int id;
    public String name;
}

Custom Adapter class:

public class DepartmentArrayAdapter extends ArrayAdapter<Department> {
    private final Context mContext;
    private final List<Department> mDepartments;
    private final List<Department> mDepartmentsAll;
    private final int mLayoutResourceId;

    public DepartmentArrayAdapter(Context context, int resource, List<Department> departments) {
        super(context, resource, departments);
        this.mContext = context;
        this.mLayoutResourceId = resource;
        this.mDepartments = new ArrayList<>(departments);
        this.mDepartmentsAll = new ArrayList<>(departments);
    }

    public int getCount() {
        return mDepartments.size();
    }

    public Department getItem(int position) {
        return mDepartments.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        try {
            if (convertView == null) {                    
                LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
                convertView = inflater.inflate(mLayoutResourceId, parent, false);
            }
            Department department = getItem(position);
            TextView name = (TextView) convertView.findViewById(R.id.textView);
            name.setText(department.name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return convertView;
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            public String convertResultToString(Object resultValue) {
                return ((Department) resultValue).name;
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                List<Department> departmentsSuggestion = new ArrayList<>();
                if (constraint != null) {
                    for (Department department : mDepartmentsAll) {
                        if (department.name.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                            departmentsSuggestion.add(department);
                        }
                    }
                    filterResults.values = departmentsSuggestion;
                    filterResults.count = departmentsSuggestion.size();
                }
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mDepartments.clear();
                if (results != null && results.count > 0) {
                    // avoids unchecked cast warning when using mDepartments.addAll((ArrayList<Department>) results.values);
                    for (Object object : (List<?>) results.values) {
                        if (object instanceof Department) {
                            mDepartments.add((Department) object);
                        }
                    }
                    notifyDataSetChanged();
                } else if (constraint == null) {
                    // no filter, add entire original list back in
                    mDepartments.addAll(mDepartmentsAll);
                    notifyDataSetInvalidated();
                }
            }
        };
    }
}

Main Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
    mAutoCompleteTextView.setThreshold(1);

    new DepartmentRequest().execute();
}

private class DepartmentRequest extends AsyncTask<Void, Void, JSONArray> {
        @Override
        protected JSONArray doInBackground(Void... voids) {
            OkHttpJsonArrayRequest request = new OkHttpJsonArrayRequest();
            try {
                return request.get("http://...");
            } catch (IOException | JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(JSONArray jsonArray) {
            super.onPostExecute(jsonArray);
            if (jsonArray != null && jsonArray.length() > 0) {
                Gson gson = new Gson();
                Department[] departments = gson.fromJson(jsonArray.toString(), Department[].class);
                mDepartmentList = Arrays.asList(departments);
                mDepartmentArrayAdapter = new DepartmentArrayAdapter(mContext, R.layout.simple_text_view, mDepartmentList);
                mAutoCompleteTextView.setAdapter(mDepartmentArrayAdapter);
            }
        }
    }

    private class OkHttpJsonArrayRequest {
        OkHttpClient client = new OkHttpClient();
        // HTTP GET REQUEST
        JSONArray get(String url) throws IOException, JSONException {
            Request request = new Request.Builder()
                    .url(url)
                    .build();
            Response response = client.newCall(request).execute();
            return new JSONArray(response.body().string());
        }
    }

Here's the screenshot:

BNK's screenshot

Hope this helps!

like image 154
BNK Avatar answered Oct 24 '22 07:10

BNK