How to Create Custom Baseadapter for Autocompletetextview

How to create custom BaseAdapter for AutoCompleteTextView

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!

How to add a custom adapter to an AutoCompleteTextView

According to the documentation, the inferred type of setAdapter in AutoCompleteTextView is :

<T extends ListAdapter & Filterable> void setAdapter(T adapter)

Your adapter must be a ListAdapter (which BaseAdapter is, so far so good) and a Filterable, which BaseAdapter is not, nor is your Adapter implementation. I would extend an ArrayAdapter, which is Filterable, not to mention is would simplify your implementation (some of your methods duplicate methods of ArrayAdapter for the same result) :

public class TwoLineDropdownAdapter extends ArrayAdapter<TwoLineDropDown> {

private LayoutInflater mInflater = null;
private Activity activity;

public TwoLineDropdownAdapter(Activity a, ArrayList<TwoLineDropDown> items) {
super(a, 0, items);
activity = a;
mInflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public static class ViewHolder {

public TextView title;
public TextView description;
}

public View getView(final int position, View convertView, ViewGroup parent) {

ViewHolder holder;

if (convertView == null) {

holder = new ViewHolder();

convertView = mInflater.inflate(R.layout.dropdown_text_twoline,
parent, false);
holder.title = (TextView) convertView
.findViewById(R.id.text1);
holder.description = (TextView) convertView
.findViewById(R.id.text2);

convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

return convertView;
}
}

android: AutoCompleteTextView with custom adapter

// try this
autoCompleteText.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> adapterView, View arg1, int position, long arg3) {
String str = (String) adapterView.getItemAtPosition(position);
autoCompleteText.setText(str);
}
});

MultiAutoCompleteTextView with custom adapter (BaseAdapter)

You need to setTokenizer() to your MultiAutoCompleteTextView in order to get it work.

You can use -

 textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());

Even you can set your own custom tokenizer if you have any special requirements else you can use CommaTokenizer which appends comma(,) everytime you select any option from the dropdown.

Autocompletetextview with custom adapter and filter

Okay i think i figure out what Luksprog was saying this code works now they key is this

mContactList = (ArrayList<Map<String, String>>) results.values;

in

@Override
public int getCount(){
return mContactList.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
false);
TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
Map<String, String> contactMap = mContactList.get(position);

nameView.setText(contactMap.get("name"));
phoneView.setText(contactMap.get("phone"));
typeView.setText(contactMap.get("type"));

return rowView;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {

if (results.count > 0) {
mContactList = (ArrayList<Map<String, String>>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}

@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
HashMap<String,String> myMap = new HashMap<String,String>();
myMap.put("name", "key");
result.add(myMap);
HashMap<String,String> myMap2 = new HashMap<String,String>();
myMap2.put("name", "is");
result.add(myMap2);
HashMap<String,String> myMap3 = new HashMap<String,String>();
myMap3.put("name", "another");
result.add(myMap3);
FilterResults r = new FilterResults();
r.values = result;
r.count = result.size();
return r;
}
};
}

How to use a custom adapter for AutoCompleteTextView

You are giving reference over here,

            ArrayList<String> mData = mList;
ArrayList<String> mSuggestions = mList;

And then clearing it,

           mSuggestions.clear();

That's why loop has no data and it was not working.

Instead declare new object, like this,

            ArrayList<String> mData = new ArrayList<String>(mList);
ArrayList<String> mSuggestions = new ArrayList<String>(mList);

Android: Set AutoCompleteTextView with a custom adapter

Make sure your adapter implements the Filterable interface.

public class CustomCardListAdapter extends BaseAdapter implements Filterable

AutoCompleteTextView does not work with custom ArrayAdapter

In your custom ArrayAdapter class, you need to override public Filter getFilter()

I have a working sample code at the following question, please take a look:

How to create custom BaseAdapter for AutoCompleteTextView

Hope this helps!



Related Topics



Leave a reply



Submit