3

I want to create a AutoCompleteTextView in which user can enter Zip Code or City Name but only City Name should be appear on suggestion drop down.

I am using AsyncTask for getting Church List, and I am using HashMap to store City Name and Zip Code.

Async Class:

    // Asynchronous Class for Fetching All Church.
public class FetchAllChurch extends AsyncTask<String, String, String> {

    Boolean isJsonObjectNull = false;
    HashMap<String, String> cityZipHashMap;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();

        progressDialog = new ProgressDialog(Search.this);
        progressDialog.setMessage("Loading Cities...");
        progressDialog.setCancelable(true);
        progressDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub
        jsonParser = new JsonParser();
        JSONObject jsonObject = jsonParser
                .makeHttpRequest(Utility.GET_ALL_CHURCH_URL);
        if (jsonObject != null) {
            Log.v("All Church: ", jsonObject.toString());
            try {
                JSONArray jsonArray = jsonObject
                        .getJSONArray(Utility.SEARCH_RESULT);

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject churchJsonObject = jsonArray
                            .getJSONObject(i);


                    String ePostalString = churchJsonObject
                            .getString(Utility.E_POSTAL);
                    String eZipCodeFullString = churchJsonObject
                            .getString(Utility.E_ZIP_FULL);
                    String eCityString = churchJsonObject
                            .getString(Utility.E_CITY);

                    cityZipHashMap = new HashMap<String, String>();
                    cityZipHashMap.put("city", eCityString);
                    cityZipHashMap.put("zip", ePostalString);
                    cityZipArrayList.add(cityZipHashMap);

                    }

                // }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);

        progressDialog.dismiss();

            AutoCompleteAdapter adapter = new AutoCompleteAdapter(
                    getApplicationContext(), android.R.layout.simple_list_item_1, cityZipArrayList);
            searchAutoCompleteTextView.setAdapter(adapter);
        }

Adapter:

Here is the adapter:

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Filterable;

public class AutoCompleteAdapter extends ArrayAdapter<String>
    implements Filterable {
private ArrayList<HashMap<String, String>> mData;

public AutoCompleteAdapter(Context context, int textViewResourceId,
        ArrayList<HashMap<String, String>> mData) {
    super(context, textViewResourceId);
    this.mData = mData;
}

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

@Override
public String getItem(int index) {
    return mData.get(index).toString();
}

@Override
public android.widget.Filter getFilter() {
    // TODO Auto-generated method stub

    android.widget.Filter filter = new android.widget.Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            // TODO Auto-generated method stub

            FilterResults filterResults = new FilterResults();
            if (constraint != null) {
                // A class that queries a web API, parses the data and
                // returns an ArrayList<Style>
                ArrayList<String> suggestion = new ArrayList<String>();
                for (int i = 0; i < getCount(); i++) {
                    if (getItem(i).startsWith(
                            constraint.toString())) {
                        suggestion.add(getItem(i));

                        Log.v("Adapter: ", getItem(i)
                                + "const" +constraint.toString());
                    }
                }

                // Now assign the values and count to the FilterResults
                // object
                filterResults.values = suggestion;

                filterResults.count = suggestion.size();
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            // TODO Auto-generated method stub

            clear();
            @SuppressWarnings("unchecked")
            ArrayList<String> newValues = (ArrayList<String>) results.values;
            for (int i = 0; i < newValues.size(); i++) {
                add(newValues.get(i));

            }

            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

    };
    return filter;
}

}

I am not getting expected result.
Thanks in advance.

Atur
  • 1,392
  • 6
  • 26
  • 37
Ashish Tiwari
  • 1,881
  • 2
  • 25
  • 49
  • 1
    see my answer here: http://stackoverflow.com/questions/19858843/how-to-dynamically-add-suggestions-to-autocompletetextview-with-preserving-chara – pskink Jul 03 '14 at 05:29

2 Answers2

1

Try this way,hope this will help you to solve your problem.

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="5dp">

    <AutoCompleteTextView
        android:id="@+id/autoComplete"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

MyActivity.java

public class MyActivity extends Activity {

    private AutoCompleteTextView autoComplete;
    ArrayList<HashMap<String,String>> cityZipList;
    ArrayList<HashMap<String,String>> autoCompleteList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

         cityZipList = new ArrayList<HashMap<String, String>>();

        HashMap<String,String> row1 = new HashMap<String, String>();
        row1.put("city","AAC");
        row1.put("zip", "123");
        cityZipList.add(row1);

        HashMap<String,String> row2 = new HashMap<String, String>();
        row2.put("city","AAD");
        row2.put("zip", "231");
        cityZipList.add(row2);

        HashMap<String,String> row3 = new HashMap<String, String>();
        row3.put("city","EFG");
        row3.put("zip", "125");
        cityZipList.add(row3);

        HashMap<String,String> row4 = new HashMap<String, String>();
        row4.put("city","AAL");
        row4.put("zip", "334");
        cityZipList.add(row4);

        HashMap<String,String> row5 = new HashMap<String, String>();
        row5.put("city","EFD");
        row5.put("zip", "235");
        cityZipList.add(row5);

        HashMap<String,String> row6 = new HashMap<String, String>();
        row6.put("city","JKL");
        row6.put("zip", "333");
        cityZipList.add(row6);

        HashMap<String,String> row7 = new HashMap<String, String>();
        row7.put("city","JKM");
        row7.put("zip", "521");
        cityZipList.add(row7);

        HashMap<String,String> row8 = new HashMap<String, String>();
        row8.put("city","AAN");
        row8.put("zip","527");
        cityZipList.add(row8);

        autoComplete = (AutoCompleteTextView) findViewById(R.id.autoComplete);
        autoComplete.setAdapter(new AutoCompleteAdapter(this,R.layout.auto_item, cityZipList));

    }

    private class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {


        public AutoCompleteAdapter(Context context, int textViewResourceId,ArrayList<HashMap<String,String>> data) {
            super(context, textViewResourceId);
        }

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

        @Override
        public String getItem(int position) {
            return autoCompleteList.get(position).get("city");
        }

        @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(final CharSequence constraint) {
                    FilterResults filterResults = new FilterResults();
                    if (constraint != null) {

                       autoCompleteList = new ArrayList<HashMap<String, String>>();
                        for (int i = 0; i < cityZipList.size(); i++) {
                            if (cityZipList.get(i).get("city").startsWith(
                                    constraint.toString()) || cityZipList.get(i).get("zip").startsWith(
                                    constraint.toString())) {
                                autoCompleteList.add(cityZipList.get(i));
                            }
                        }

                        // Now assign the values and count to the FilterResults
                        // object
                        filterResults.values = autoCompleteList;

                        filterResults.count = autoCompleteList.size();
                    }
                    return filterResults;
                }

                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    if (results != null && results.count > 0) {
                        notifyDataSetChanged();
                    } else {
                        notifyDataSetInvalidated();
                    }
                }
            };
            return filter;
        }
    }

}
Haresh Chhelana
  • 23,930
  • 5
  • 51
  • 66
  • I did replace the code. Now Suggestion is appearing like "34678-cityname" but filtering is not working. all cities are appearing in suggestion. – Ashish Tiwari Jul 03 '14 at 06:14
  • have you check data in for loop ? – Haresh Chhelana Jul 03 '14 at 06:38
  • @AshishTiwari why do yo want to implement your custom adapter, custom async task and custom filter instead of doing what i did in my comment above? – pskink Jul 03 '14 at 06:42
  • @pskink I am using custom adapter because I want to call the api only once and store the city and zip in array or hashmap. Does your code call the api only once? Now I am going to try your code. – Ashish Tiwari Jul 03 '14 at 07:25
  • @AshishTiwari runQuery is called each time you type something in ACTV and in order not to load possible huge data with all items it gets it depending on "contraint" variable but its perfectly up to you if you contact web service once or each time you type anything – pskink Jul 03 '14 at 07:56
  • @pskink I am not getting output. I am unable to understand how can i compare cityName and zipCode to typed character and how to display matched suggestion. – Ashish Tiwari Jul 03 '14 at 11:12
  • in suggestion list all cities are appearing without filtering. Please tell me what should I do for comparing typed character to cityName and zipCode. – Ashish Tiwari Jul 03 '14 at 11:41
  • have you run my code? it gets data from wikipedia open search api, add a breakpoint in the beggining of runQuery method and step by step debug it, it will explain how it works – pskink Jul 03 '14 at 11:53
  • @pskink Yes Its working now. I have removed code for getting data from API, and place there List of HashMap that contains city and zip. Thank You :) – Ashish Tiwari Jul 04 '14 at 04:34
  • @Haresh Yes your code is also working.. :) I am happy I got the two ways to do one thing. Thank you. – Ashish Tiwari Jul 04 '14 at 04:36
0

Use this custom adapter I have used in my code. I have used this adapter with hashmaps.

public class AutoCompleteSearchViewAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<HashMap<String, String>> fullList = new ArrayList<>();
private ArrayList<HashMap<String, String>> filteredList = new ArrayList<>();

public AutoCompleteSearchViewAdapter(Context context, int resource, ArrayList<HashMap<String, String>> fullList) {
    super(context, resource);
    this.fullList = fullList;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return super.getView(position, convertView, parent);
}

@Override
public Filter getFilter() {
    android.widget.Filter filter = new android.widget.Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if (constraint != null) {
                ArrayList<HashMap<String, String>> suggestion = new ArrayList<HashMap<String, String>>();
                for (int i = 0; i < fullList.size(); i++) {
                    if (fullList.get(i).get("productName").toUpperCase().startsWith(((String) constraint).toUpperCase())) {
                        suggestion.add(fullList.get(i));
                    }
                }
                filterResults.values = suggestion;
                filterResults.count = suggestion.size();
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredList.clear();
            if (results.values != null) {
                ArrayList<HashMap<String, String>> newValues = (ArrayList<HashMap<String, String>>) results.values;

                for (int i = 0; i < newValues.size(); i++) {
                    filteredList.add(newValues.get(i));
                }
            }
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

    };
    return filter;
}


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

@Override
public String getItem(int position) {
    return filteredList.get(position).get("productName");
}
}
Akash Bisariya
  • 2,431
  • 1
  • 24
  • 39