How to customize PlaceAutocomplete widget dialog design to list places

后端 未结 4 1183
刺人心
刺人心 2020-12-13 01:01

I need to show list of places in dropdown using google placeAutocomplete widgets. Here I\'m getting dialog to show places according to my query but

4条回答
  •  没有蜡笔的小新
    2020-12-13 01:24

    In view of the latest changes in the AutocompletePrediction API, here is the revised Adapter and Filter code:

    PlaceAutoCompleteAdapter.java

    package com.equinox.prologix.Adapters;
    
    import android.content.Context;
    import android.os.Handler;
    import android.os.Message;
    import android.support.annotation.NonNull;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Filter;
    import android.widget.Filterable;
    import android.widget.Toast;
    
    import com.equinox.prologix.Activities.LocationChooseActivity;
    import com.equinox.prologix.Filters.PlaceAutoCompleteFilter;
    import com.equinox.prologix.R;
    import com.equinox.prologix.ViewHolders.PlaceAutoCompleteHolder;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.places.AutocompletePrediction;
    import com.google.android.gms.location.places.GeoDataClient;
    import com.google.android.gms.location.places.Place;
    import com.google.android.gms.location.places.PlaceBufferResponse;
    import com.google.android.gms.location.places.Places;
    import com.google.android.gms.location.places.ui.PlaceAutocomplete;
    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.model.LatLngBounds;
    import com.google.android.gms.tasks.OnCompleteListener;
    import com.google.android.gms.tasks.Task;
    
    import java.util.List;
    
    /**
     * Created by Mohammed Mukhtar on 12/1/2017.
     */
    
    public class PlaceAutoCompleteAdapter extends RecyclerView.Adapter implements Filterable {
    
        private Context context;
        private GoogleMap googleMap;
        private PlaceAutoCompleteFilter placeAutoCompleteFilter;
        private GeoDataClient mGeoDataClient;
        private GoogleApiClient googleApiClient;
        private Handler autoCompleteSelected;
        private List resultPlaceList;
    
        public PlaceAutoCompleteAdapter(Context context, GoogleApiClient googleApiClient, List resultPlaceList, Handler autoCompleteSelected) {
            this.context = context;
            this.resultPlaceList = resultPlaceList;
            this.googleApiClient = googleApiClient;
            this.autoCompleteSelected = autoCompleteSelected;
            mGeoDataClient = Places.getGeoDataClient(context, null);
        }
    
        @Override
        public PlaceAutoCompleteHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(context).inflate(R.layout.list_item_google_place_autocomplete, parent, false);
            return new PlaceAutoCompleteHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(final PlaceAutoCompleteHolder holder, final int position) {
            final AutocompletePrediction autocompletePrediction = resultPlaceList.get(position);
            holder.getLocationAddressView().setText(autocompletePrediction.getPrimaryText(null));
            holder.getLocationLocalityView().setText(autocompletePrediction.getSecondaryText(null));
            holder.getItemView().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mGeoDataClient.getPlaceById(autocompletePrediction.getPlaceId()).addOnCompleteListener(new OnCompleteListener() {
                        @Override
                        public void onComplete(@NonNull Task task) {
                            if (task.isSuccessful()) {
                                PlaceBufferResponse places = task.getResult();
                                Place myPlace = places.get(0);
                                googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPlace.getLatLng(), 17));
                                autoCompleteSelected.sendMessage(Message.obtain());
                                Log.i("getPlaceById", "Place found: " + myPlace.getName());
                                places.release();
                            } else Log.e("getPlaceById", "Place not found.");
                        }
                    });
                    Toast.makeText(context, resultPlaceList.get(holder.getAdapterPosition()).getFullText(null), Toast.LENGTH_LONG).show();
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return resultPlaceList.size();
        }
    
        @Override
        public Filter getFilter() {
            if (placeAutoCompleteFilter == null)
                placeAutoCompleteFilter = new PlaceAutoCompleteFilter(googleApiClient, this, resultPlaceList);
            return placeAutoCompleteFilter;
        }
    
        public void setGoogleMap(GoogleMap googleMap) {
            this.googleMap = googleMap;
        }
    }
    

    PlaceAutoCompleteFilter.java

    package com.equinox.prologix.Filters;
    
    import android.text.style.CharacterStyle;
    import android.util.Log;
    import android.widget.Filter;
    
    import com.equinox.prologix.Adapters.PlaceAutoCompleteAdapter;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.common.api.PendingResult;
    import com.google.android.gms.common.api.Status;
    import com.google.android.gms.location.places.AutocompleteFilter;
    import com.google.android.gms.location.places.AutocompletePrediction;
    import com.google.android.gms.location.places.AutocompletePredictionBuffer;
    import com.google.android.gms.location.places.Place;
    import com.google.android.gms.location.places.Places;
    import com.google.android.gms.location.places.ui.PlaceAutocomplete;
    import com.google.android.gms.maps.model.LatLngBounds;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.TimeUnit;
    
    import static com.equinox.prologixappcommon.Models.DataHolderCommon.currentCountry;
    import static com.equinox.prologixappcommon.Models.DataHolderCommon.currentLocation;
    import static com.equinox.prologixappcommon.Utils.BackendTransform.transform;
    import static com.equinox.prologixappcommon.Utils.BackendTransform.transform2;
    import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_NONE;
    
    /**
     * Created by Mohammed Mukhtar on 12/1/2017.
     */
    
    public class PlaceAutoCompleteFilter extends Filter {
    
        private GoogleApiClient mGoogleApiClient;
        private PlaceAutoCompleteAdapter placeAutoCompleteAdapter;
        private List resultPlaceList;
    
        public PlaceAutoCompleteFilter(GoogleApiClient mGoogleApiClient,
                                       PlaceAutoCompleteAdapter placeAutoCompleteAdapter,
                                       List resultPlaceList) {
            this.mGoogleApiClient = mGoogleApiClient;
            this.placeAutoCompleteAdapter = placeAutoCompleteAdapter;
            this.resultPlaceList = resultPlaceList;
        }
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            // Skip the autocomplete query if no constraints are given.
            if (constraint != null) {
                // Query the autocomplete API for the (constraint) search string.
                List tempResult = getAutoComplete(constraint);
                if (tempResult != null) {
                    results.values = tempResult;
                    results.count = tempResult.size();
                }
            }
            return results;
        }
    
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                resultPlaceList.clear();
                resultPlaceList.addAll((List) results.values);
                placeAutoCompleteAdapter.notifyDataSetChanged();
            }
            else {
                // The API did not return any results, invalidate the data set.
    
            }
        }
    
        private ArrayList getAutoComplete(CharSequence constraint) {
            if (mGoogleApiClient.isConnected()) {
                Log.i("", "Starting autocomplete query for: " + constraint);
    
                AutocompleteFilter autocompleteFilter = new AutocompleteFilter.Builder()
                        //.setCountry(currentCountry.getCountryCode())
                        .setTypeFilter(TYPE_FILTER_NONE)
                        .build();
    
                // Submit the query to the autocomplete API and retrieve a PendingResult that will
                // contain the results when the query completes.
                PendingResult results =
                        Places.GeoDataApi
                                .getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
                                        new LatLngBounds.Builder().include(transform(currentLocation)).build(),
                                        autocompleteFilter);
    
                // This method should have been called off the main UI thread. Block and wait for at most 60s
                // for a result from the API.
                AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
    
                // Confirm that the query completed successfully, otherwise return null
                final Status status = autocompletePredictions.getStatus();
                if (!status.isSuccess()) {
    //                Toast.makeText(mContext, "Error contacting API: " + status.toString(),
    //                        Toast.LENGTH_SHORT).show();
                    Log.e("", "Error getting autocomplete prediction API call: " + status.toString());
                    autocompletePredictions.release();
                    return null;
                }
    
                Log.i("", "Query completed. Received " + autocompletePredictions.getCount()
                        + " predictions.");
    
                // Copy the results into our own data structure, because we can't hold onto the buffer.
                // AutocompletePrediction objects encapsulate the API response (place ID and description).
    
                Iterator iterator = autocompletePredictions.iterator();
                ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
                while (iterator.hasNext()) {
                    AutocompletePrediction prediction = iterator.next();
                    resultList.add(prediction.freeze());
                }
    
                // Release the buffer now that all data has been copied.
                autocompletePredictions.release();
    
                return resultList;
            }
            Log.e("", "Google API client is not connected for autocomplete query.");
            return null;
        }
    
    }
    

提交回复
热议问题