I have an Android Application, and there's a part where the user can use an AutoCompleteTextView
to select names. The user can select a name and then details (such as address) would appear in the next activity. What I do is that when the user selects a name, I get that name's position from the ArrayList
, and go to my Address ArrayList, get the address at the same position, and then I have my data.
However, some of the names tend to repeat, for example, I have a Name ArrayList as such:
[A, B, B, C]
and an Address ArrayList as such:
[Address A, Address B, Address C, Address D]
when the user clicks the 2nd B in the AutoCompleteTextView, the position returned will be that of the first B, NOT the second B, and therefore, it will give the Address B instead of Address C.
I've looked around and I've tried to make my custom ArrayAdapter
for my AutoCompleteTextView
to display my custom class with the Name and the Address. However, I did not have much luck with that.
The next thing I looked into was to using a HashMap<String, String>
as shown in thisStackOverflow Question. It is very similar to what is used for a Custom ListView, only that it has a getFilter
function. I have tried to adapt that code as such:
public class actvMapFilter extends
ArrayAdapter<Map<String, String>> implements Filterable {
private Context mContext;
private List<Map<String, String>> mClientList;
private List<Map<String, String>> mMutableList;
public actvMapFilter(Context context,
List<Map<String, String>> objects) {
super(context, android.R.layout.simple_list_item_1, objects);
mContext = context;
mClientList = objects;
// TODO Auto-generated constructor stub
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(android.R.layout.simple_dropdown_item_1line, null);
}
TextView nameView = (TextView) v.findViewById(android.R.id.text1);
if(position < mClientList.size()){
Map<String, String> clientMap = mClientList.get(position);
nameView.setText(clientMap.keySet().toArray()[position].toString());
}
return v;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results.count > 0) {
mClientList = (ArrayList<Map<String, String>>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
HashMap<String,String> myMap = new HashMap<String,String>();
if(constraint != null && mClientList!=null){
int length = mClientList.size();
int i = 0;
Log.e("","constraint = " + constraint.toString().toUpperCase());
Log.e("","constraint and list not null.");
Log.e("","length of original list = " + length);
while(i < length){
String key = mClientList.get(i).keySet().toArray()[0].toString();
String value = mClientList.get(i).values().toArray()[0].toString();
if(key.contains(constraint.toString().toUpperCase())){
myMap.put(key, value);
result.add(myMap);
}
i++;
}
Log.e("","filter results = " + myMap);
Log.e("","filter results count = " + myMap.size());
filterResults.values = result;
filterResults.count = result.size();
}
FilterResults r = new FilterResults();
r.values = result;
r.count = result.size();
return r;
}
};
}
}
It is very similar to what was marked as the answer. However, what I do in my getFilter
function is that when I have a constraint
given, I check if the key
part contains the constraints, I add those.
This works well, I am told by my LogCat that if I type a certain character, my resulting HashMap would contain the entries with the constrains only.
However, what happens is that when I type in a 2nd succeeding character, the filter does not seem to work any more. I am given a blank filtered result HashMap and the dropdown menu reflects the blank result because I don't have any suggestive text any more.
How can I implement a Filterable ArrayAdapter properly?