android autocompletetextview with - How to customize PlaceAutocomplete widget dialog design to list places


1 Answers

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<PlaceAutoCompleteHolder> implements Filterable {

    private Context context;
    private GoogleMap googleMap;
    private PlaceAutoCompleteFilter placeAutoCompleteFilter;
    private GeoDataClient mGeoDataClient;
    private GoogleApiClient googleApiClient;
    private Handler autoCompleteSelected;
    private List<AutocompletePrediction> resultPlaceList;

    public PlaceAutoCompleteAdapter(Context context, GoogleApiClient googleApiClient, List<AutocompletePrediction> 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<PlaceBufferResponse>() {
                    @Override
                    public void onComplete(@NonNull Task<PlaceBufferResponse> 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<AutocompletePrediction> resultPlaceList;

    public PlaceAutoCompleteFilter(GoogleApiClient mGoogleApiClient,
                                   PlaceAutoCompleteAdapter placeAutoCompleteAdapter,
                                   List<AutocompletePrediction> 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<AutocompletePrediction> 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<AutocompletePrediction>) results.values);
            placeAutoCompleteAdapter.notifyDataSetChanged();
        }
        else {
            // The API did not return any results, invalidate the data set.

        }
    }

    private ArrayList<AutocompletePrediction> 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<AutocompletePredictionBuffer> 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<AutocompletePrediction> iterator = autocompletePredictions.iterator();
            ArrayList<AutocompletePrediction> 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;
    }

}
google api github

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 I need to give custom design for that search result dialog as like in Uber, Ola apps. Here I want design like below image. If anyone done this before please give me your suggestions,thanks in advance.



Related