0

I am building an android application where I am using AutoComplete text to show the search of google place name.

Now the problem is I want to dismiss the list when I selected any item from the listview.

Here is my code -

!. oncreateview -

atvPlaces = (AutoCompleteTextView) findViewById(R.id.atv_places);
atvPlaces.setThreshold(1);      

atvPlaces.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before, int 
count) {                
    placesTask = new PlacesTask();              
    placesTask.execute(s.toString());
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
    // TODO Auto-generated method stub
}

@Override
public void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub              
}
});

/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
    URL url = new URL(strUrl);                

    // Creating an http connection to communicate with url 
    urlConnection = (HttpURLConnection) url.openConnection();

    // Connecting to url 
    urlConnection.connect();

    // Reading data from url 
    iStream = urlConnection.getInputStream();

    BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

    StringBuffer sb  = new StringBuffer();

    String line = "";
    while( ( line = br.readLine())  != null){
            sb.append(line);
    }

    data = sb.toString();

    br.close();

   }catch(Exception e){
    Log.d("Exception while downloading url", e.toString());
   }finally{
    iStream.close();
    urlConnection.disconnect();
   }
   return data;
   }  

 // Fetches all places from GooglePlaces AutoComplete Web Service
 private class PlacesTask extends AsyncTask<String, Void, String>{

 @Override
 protected String doInBackground(String... place) {
// For storing data from web service
String data = "";

// Obtain browser key from https://code.google.com/apis/console
String key = "key";

String input="";



try {
    input = "input=" + URLEncoder.encode(place[0], "utf-8");
    input = input.replaceAll(" ", "%20");
} catch (UnsupportedEncodingException e1) {
    e1.printStackTrace();
}       


// place type to be searched
String types = "types=geocode";

// Sensor enabled
String sensor = "sensor=false";         

// Building the parameters to the web service
String parameters = input+"&"+types+"&"+sensor+"&"+key;

// Output format
String output = "json";

// Building the url to the web service
String url = 

"https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+

 parameters;

try{
    // Fetching the data from web service in background
    data = downloadUrl(url);
}catch(Exception e){
    Log.d("Background Task",e.toString());
}
return data;        
}

 @Override
 protected void onPostExecute(String result) {           
super.onPostExecute(result);

// Creating ParserTask
parserTask = new ParserTask();

// Starting Parsing the JSON string returned by Web Service
parserTask.execute(result);
}       
}


/** A class to parse the Google Places in JSON format */
private class ParserTask extends AsyncTask<String, Integer, 
List<HashMap<String,String>>>{

 JSONObject jObject;

@Override
protected List<HashMap<String, String>> doInBackground(String...   
jsonData) {         

List<HashMap<String, String>> places = null;

PlaceJSONParser placeJsonParser = new PlaceJSONParser();

try{
    jObject = new JSONObject(jsonData[0]);

    // Getting the parsed data as a List construct
    places = placeJsonParser.parse(jObject);

}catch(Exception e){
    Log.d("Exception",e.toString());
}
return places;
}

@Override
 protected void onPostExecute(List<HashMap<String, String>> result) {            

    String[] from = new String[] { "description"};
    int[] to = new int[] { android.R.id.text1 };

    // Creating a SimpleAdapter for the AutoCompleteTextView            
    SimpleAdapter adapter = new SimpleAdapter(getBaseContext(),  
    result, android.R.layout.simple_list_item_1, from, to);             

    atvPlaces.showDropDown();
        // Setting the adapter
        atvPlaces.setAdapter(adapter);

        atvPlaces.setOnItemClickListener(new    
        AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int   
       position, long id) {
                atvPlaces.dismissDropDown();
                String a = search_bar.getText().toString();
                a = a.substring(0, Math.min(a.length(), 12));
                atvPlaces.setText(a+"...");
            }
        });


}           
}    

Here is placejson code -

public class PlaceJSONParser {

  /**
  * Receives a JSONObject and returns a list
  */
 public List<HashMap<String, String>> parse(JSONObject jObject) {

JSONArray jPlaces = null;
try {
    /** Retrieves all the elements in the 'places' array */
    jPlaces = jObject.getJSONArray("predictions");
} catch (JSONException e) {
    e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
 * where each json object represent a place
 */
return getPlaces(jPlaces);
}


private List<HashMap<String, String>> getPlaces(JSONArray jPlaces) {
int placesCount = jPlaces.length();
List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,     
String>>();
HashMap<String, String> place = null;

/** Taking each place, parses and adds to list object */
for (int i = 0; i < placesCount; i++) {
    try {
        /** Call getPlace with place JSON object to parse the place */
        place = getPlace((JSONObject) jPlaces.get(i));
        placesList.add(place);

    } catch (JSONException e) {
        e.printStackTrace();
    }
}

return placesList;
}

 /**
  * Parsing the Place JSON object
  */
 private HashMap<String, String> getPlace(JSONObject jPlace) {

HashMap<String, String> place = new HashMap<String, String>();

String id = "";
String reference = "";
String description = "";

try {

    description = jPlace.getString("description");
    id = jPlace.getString("id");
    reference = jPlace.getString("reference");

    place.put("description", description);
    place.put("_id", id);
    place.put("reference", reference);

} catch (JSONException e) {
    e.printStackTrace();
}
 return place;
}
}
sof question
  • 93
  • 2
  • 13
  • Clear the Array or ArrayList used in adapter and then use adapter.notifyDatasetChanged(); or You can use a new adapter with empty Array or list. – Umesh Chhabra Mar 16 '15 at 09:50
  • @UmeshChhabra THanks for answering. can you please help me in telling where to use adapter.notifyDatasetChanged(); – sof question Mar 16 '15 at 11:08
  • Try: atvPlaces.setAdapter(null); at the end of your onItemClick method. – dev.bmax Mar 16 '15 at 11:42
  • @dev.bmax Dose not work. :( – sof question Mar 16 '15 at 11:48
  • NotifyDatasetChanged will not work for you. Because you are creating a whole new adapter every time in your onPostExecute. – Umesh Chhabra Mar 16 '15 at 12:04
  • If atvPlaces.setAdapter(null); does not work then use ////////////////////////SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, new ArrayList,to ); atvPlaces.setAdapter(adapter); at the end of your onItemClick method. – Umesh Chhabra Mar 16 '15 at 12:10
  • I mean to say replace adapter with new adapter that has blank arraylist. – Umesh Chhabra Mar 16 '15 at 12:12
  • I must say, your approach is not good, you are creating new adapter and setting onItemClickListener every time onPostExecute called. – Umesh Chhabra Mar 16 '15 at 12:14

2 Answers2

0

Got it! Calling atvPlaces.setText() in the onItemClick triggers the PlacesTask all over again.

So you would need to call atvPlaces.removeTextChangedListener() before you call atvPlaces.setText().

And you can set the listener back after you update the text.

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        atvPlaces = (AutoCompleteTextView) findViewById(R.id.atv_places);
        atvPlaces.setThreshold(1);
        mTextWatcher = new MyTextWatcher();
        atvPlaces.addTextChangedListener(mTextWatcher);
}
        protected void onPostExecute(final List<HashMap<String, String>> result) {
            String[] from = new String[] {"description"};
            int[] to = new int[] { android.R.id.text1 };

            SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, result,
                    android.R.layout.simple_list_item_1, from, to);
            atvPlaces.setAdapter(adapter);
            atvPlaces.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    atvPlaces.removeTextChangedListener(mTextWatcher);
                    String a = search_bar.getText().toString();
                    a = a.substring(0, Math.min(a.length(), 12));
                    atvPlaces.setText(a+"...");    
                    atvPlaces.dismissDropDown();
                    atvPlaces.addTextChangedListener(mTextWatcher);
                }
            });
            atvPlaces.performValidation();
            atvPlaces.showDropDown();
        }
    private class MyTextWatcher implements TextWatcher {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int
        count) {
            placesTask = new PlacesTask();
            placesTask.execute(s.toString());
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
            // TODO Auto-generated method stub
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
        }
    }
dev.bmax
  • 8,998
  • 3
  • 30
  • 41
  • I have tried it and it works for me... The drop down list disappears right after I click on one of the items. Please explain what exactly is wrong in your case and how you want it to be. – dev.bmax Mar 17 '15 at 15:10
  • I am also facing same problem and tried all on stack over flow – Rahul Chaudhary Nov 24 '15 at 05:27
0

Try using post(Runnable r) method with the AutoCompleteTextView like this:

atvPlaces.post(new Runnable() {
    public void run() {
        atvPlaces.dismissDropDown();
    }
}

Hope that Helps!1

AniV
  • 3,997
  • 1
  • 12
  • 17
  • can you please help me in telling how can I use this – sof question Mar 17 '15 at 10:42
  • So this is a separate thread that would run just to execute the dismissDropDown() method. Now you have to place this piece of code when the user selects one item from the dropdown. That will be the onItemClick() method. – AniV Mar 17 '15 at 23:48