AutoCompleteTextView with Google Places shown in ListView just like Uber

前端 未结 3 888
旧巷少年郎
旧巷少年郎 2020-12-14 12:05

I need to make screen similar to this. I think it has autocompletetextview and listview to display returned results. Google Place API is used here to auto suggest places and

3条回答
  •  暖寄归人
    2020-12-14 12:46

    You can achieve this exactly by using EditText and ListView, and not AutoCompleteTextView. Characters are entered in the EditText on the basis of which the results in the ListView are filtered by calling the GooglePlacesAutomplete webservice. The following is the code:

    This is your layoout file ( EditText with ListView )

    
    
        
            
        
    
    
    
    
    

    In your corresponding Activity, access this EditText and apply Filterable. You have to use GooglePlacesAutompleteAdapter for this.

    The following is the GooglePlacesAutompleteAdapter :

    public class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable {
    private static final String LOG_TAG = "Google Places Autocomplete";
    private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
    private static final String OUT_JSON = "/json";
    private static final String API_KEY = "your_api_key";
    private ArrayList resultList;
    private Context context = null;
    public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        this.context = context;
    }
    
    
    @Override
    public int getCount() {
        if(resultList != null)
            return resultList.size();
        else
            return 0;
    }
    
    @Override
    public String getItem(int index) {
        return resultList.get(index);
    }
    
    
    public ArrayList autocomplete(String input) {
        ArrayList resultList = null;
        ArrayList descriptionList = null;
        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();
        try {
            StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
            sb.append("?key=" + API_KEY);
            sb.append("&components=country:in");
            sb.append("&input=" + URLEncoder.encode(input, "utf8"));
    
            URL url = new URL(sb.toString());
            conn = (HttpURLConnection) url.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());
    
            // Load the results into a StringBuilder
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
            return resultList;
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
            return resultList;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    
        try {
            // Create a JSON object hierarchy from the results
            Log.d("yo",jsonResults.toString());
            JSONObject jsonObj = new JSONObject(jsonResults.toString());
            JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
    
            // Extract the Place descriptions from the results
            resultList = new ArrayList(predsJsonArray.length());
            descriptionList = new ArrayList(predsJsonArray.length());
            for (int i = 0; i < predsJsonArray.length(); i++) {
                resultList.add(predsJsonArray.getJSONObject(i).toString());
                descriptionList.add(predsJsonArray.getJSONObject(i).getString("description"));
            }
            saveArray(resultList.toArray(new String[resultList.size()]), "predictionsArray", getContext());
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Cannot process JSON results", e);
        }
    
        return descriptionList;
    }
    
    
    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                if (constraint != null) {
                    // Retrieve the autocomplete results.
                    resultList = autocomplete(constraint.toString());
    
                    // Assign the data to the FilterResults
                    filterResults.values = resultList;
                    filterResults.count = resultList.size();
                }
                return filterResults;
            }
    
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.count > 0) {
                    setImageVisibility();
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        };
        return filter;
    }
    }
    

    Access the adapter and apply getFilter() to the EditText in the corresponding Activity. The following is to be added in your Activity corresponding to your layout created earlier:

    dataAdapter = new   GooglePlacesAutocompleteAdapter(EnterLocationActivity.this, R.layout.adapter_google_places_autocomplete){
    
    listView = (ListView) findViewById(R.id.listView1);
        // Assign adapter to ListView
        listView.setAdapter(dataAdapter);
    
        //enables filtering for the contents of the given ListView
        listView.setTextFilterEnabled(true);
    
    etEnterLocation.addTextChangedListener(new TextWatcher() {
    
            public void afterTextChanged(Editable s) {
            }
    
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
    
            public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                dataAdapter.getFilter().filter(s.toString());
            }
        });
    

    This should get you going. You can modify your layout as you want. This basically loads the autocomplete data in a ListView.

提交回复
热议问题