web-dev-qa-db-ja.com

PlaceAutocompleteウィジェットダイアログデザインをカスタマイズして場所をリストする方法

Google dropdownウィジェットを使用して、placeAutocompleteの場所のリストを表示する必要があります。ここでは、クエリに従って場所を表示するダイアログが表示されますが、Uber、Olaアプリのように、その検索結果ダイアログにカスタムデザインを指定する必要があります。ここでは、次の画像のようなデザインが必要です。誰もがこれを以前に行った場合、私にあなたの提案をお願いします、事前に感謝します。

enter image description here

27
Moorthy

アダプタをカスタマイズする必要があります。この機能をプロジェクトに実装しました。これに従うことができます。

activity_search.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/parent"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    Android:background="@color/white">

    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        >
        <LinearLayout
            Android:id="@+id/search_layout"
            Android:layout_width="match_parent"
            Android:layout_height="50dp"
            Android:gravity="center_vertical"
            Android:layout_alignParentTop="true"
            Android:background="@drawable/searchbar_bg"
            Android:layout_marginLeft="@dimen/activity_margin_10"
            Android:layout_marginRight="@dimen/activity_margin_10"
            Android:layout_marginTop="@dimen/activity_margin_10"
            Android:orientation="vertical">

                <RelativeLayout
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent">
                    <EditText
                        Android:id="@+id/search_et"
                        Android:layout_width="match_parent"
                        Android:layout_height="match_parent"
                        Android:hint="Search"
                        Android:singleLine="true"
                        Android:layout_toLeftOf="@+id/clear"
                        Android:imeOptions="actionSearch"
                        Android:background="@null"
                        Android:drawableLeft="@drawable/ic_action_search"
                        Android:drawablePadding="@dimen/activity_margin_10"
                        Android:paddingLeft="@dimen/activity_margin_10"
                        Android:paddingRight="@dimen/activity_margin_10"/>
                    <ImageView
                        Android:id="@+id/clear"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:src="@drawable/ic_clear"
                        Android:layout_alignParentRight="true"
                        Android:layout_gravity="right|center_vertical"
                        Android:padding="@dimen/activity_margin_16"
                        Android:visibility="gone"/>
                </RelativeLayout>


        </LinearLayout>


        <Android.support.v7.widget.RecyclerView
            Android:id="@+id/list_search"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_below="@+id/search_layout"
            Android:layout_above="@+id/powered_by_google"
            Android:background="@color/white"
            Android:layout_marginTop="@dimen/activity_margin_10"/>

        <ImageView
            Android:id="@+id/powered_by_google"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_centerHorizontal="true"
            Android:layout_alignParentBottom="true"
            Android:padding="@dimen/activity_margin_10"
            Android:layout_marginBottom="@dimen/activity_margin_10"
            Android:src="@drawable/powered_by_google_light"/>
    </RelativeLayout>
</LinearLayout>

SearchActivity.Java

package com.Android.dezi.views.rider.Activities;

import Android.content.Context;
import Android.content.Intent;
import Android.os.Bundle;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.text.Editable;
import Android.text.TextWatcher;
import Android.util.Log;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.widget.EditText;
import Android.widget.ImageView;
import Android.widget.LinearLayout;
import Android.widget.Toast;

import com.Android.dezi.BaseActivity;
import com.Android.dezi.R;
import com.Android.dezi.adapters.PlaceAutocompleteAdapter;
import com.Android.dezi.adapters.PlaceAutocompleteAdapter.PlaceAutoCompleteInterface;
import com.Android.dezi.adapters.PlaceSavedAdapter;
import com.Android.dezi.adapters.PlaceSavedAdapter.SavedPlaceListener;
import com.Android.dezi.beans.SavedAddress;
import com.Android.dezi.views.rider.Fragments.SearchFragment;
import com.google.Android.gms.common.ConnectionResult;
import com.google.Android.gms.common.api.GoogleApiClient;
import com.google.Android.gms.common.api.PendingResult;
import com.google.Android.gms.common.api.ResultCallback;
import com.google.Android.gms.location.LocationServices;
import com.google.Android.gms.location.places.Place;
import com.google.Android.gms.location.places.PlaceBuffer;
import com.google.Android.gms.location.places.Places;
import com.google.Android.gms.location.places.ui.PlaceAutocomplete;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.OnMapReadyCallback;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.LatLngBounds;

import Java.util.ArrayList;
import Java.util.List;

/**
 * Created by anuj.sharma on 4/6/2016.
 */
public class SearchActivity extends BaseActivity implements PlaceAutoCompleteInterface, GoogleApiClient.OnConnectionFailedListener,
        GoogleApiClient.ConnectionCallbacks,OnClickListener,SavedPlaceListener {
    Context mContext;
    GoogleApiClient mGoogleApiClient;

    LinearLayout mParent;
    private RecyclerView mRecyclerView;
    LinearLayoutManager llm;
    PlaceAutocompleteAdapter mAdapter;
    List<SavedAddress> mSavedAddressList;
    PlaceSavedAdapter mSavedAdapter;
    private static final LatLngBounds BOUNDS_INDIA = new LatLngBounds(
            new LatLng(-0, 0), new LatLng(0, 0));

    EditText mSearchEdittext;
    ImageView mClear;

    @Override
    public void onStart() {
        mGoogleApiClient.connect();
        super.onStart();

    }

    @Override
    public void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_search);
        mContext = SearchActivity.this;

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, 0 /* clientId */, this)
                .addApi(Places.GEO_DATA_API)
                .build();

        initViews();
    }

    /*
   Initialize Views
    */
    private void initViews(){
        mRecyclerView = (RecyclerView)findViewById(R.id.list_search);
        mRecyclerView.setHasFixedSize(true);
        llm = new LinearLayoutManager(mContext);
        mRecyclerView.setLayoutManager(llm);

        mSearchEdittext = (EditText)findViewById(R.id.search_et);
        mClear = (ImageView)findViewById(R.id.clear);
        mClear.setOnClickListener(this);

        mAdapter = new PlaceAutocompleteAdapter(this, R.layout.view_placesearch,
                mGoogleApiClient, BOUNDS_INDIA, null);
        mRecyclerView.setAdapter(mAdapter);

        mSearchEdittext.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (count > 0) {
                    mClear.setVisibility(View.VISIBLE);
                    if (mAdapter != null) {
                        mRecyclerView.setAdapter(mAdapter);
                    }
                } else {
                    mClear.setVisibility(View.GONE);
                    if (mSavedAdapter != null && mSavedAddressList.size() > 0) {
                        mRecyclerView.setAdapter(mSavedAdapter);
                    }
                }
                if (!s.toString().equals("") && mGoogleApiClient.isConnected()) {
                    mAdapter.getFilter().filter(s.toString());
                } else if (!mGoogleApiClient.isConnected()) {
//                    Toast.makeText(getApplicationContext(), Constants.API_NOT_CONNECTED, Toast.LENGTH_SHORT).show();
                    Log.e("", "NOT CONNECTED");
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

    }

    @Override
    public void onClick(View v) {
        if(v == mClear){
            mSearchEdittext.setText("");
            if(mAdapter!=null){
                mAdapter.clearList();
            }

        }
    }



    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    @Override
    public void onPlaceClick(ArrayList<PlaceAutocompleteAdapter.PlaceAutocomplete> mResultList, int position) {
        if(mResultList!=null){
            try {
                final String placeId = String.valueOf(mResultList.get(position).placeId);
                        /*
                             Issue a request to the Places Geo Data API to retrieve a Place object with additional details about the place.
                         */

                PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
                        .getPlaceById(mGoogleApiClient, placeId);
                placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() {
                    @Override
                    public void onResult(PlaceBuffer places) {
                        if(places.getCount()==1){
                            //Do the things here on Click.....
                            Intent data = new Intent();
                            data.putExtra("lat",String.valueOf(places.get(0).getLatLng().latitude));
                            data.putExtra("lng", String.valueOf(places.get(0).getLatLng().longitude));
                            setResult(SearchActivity.RESULT_OK, data);
                            finish();
                        }else {
                            Toast.makeText(getApplicationContext(),"something went wrong",Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
            catch (Exception e){

            }

        }
    }

    @Override
    public void onSavedPlaceClick(List<SavedAddress> mResponse, int position) {
        if(mResponse!=null){
            try {
                Intent data = new Intent();
                data.putExtra("lat",String.valueOf(mResponse.get(position).getLatitude()));
                data.putExtra("lng", String.valueOf(mResponse.get(position).getLongitude()));
                setResult(SearchActivity.RESULT_OK, data);
                finish();
            }
            catch (Exception e){

            }

        }
    }
}

PlaceAutocompleteAdapter.Java

これはカスタマイズされたアダプターです。すべての重要な部分はこの中にあります。

package com.Android.dezi.adapters;

import Android.content.Context;
import Android.graphics.Typeface;
import Android.support.v7.widget.RecyclerView;
import Android.text.style.CharacterStyle;
import Android.text.style.StyleSpan;
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.ImageView;
import Android.widget.LinearLayout;
import Android.widget.RelativeLayout;
import Android.widget.TextView;
import Android.widget.Toast;

import com.Android.dezi.R;
import com.Android.dezi.beans.TripHistoryBean;
import com.Android.dezi.views.rider.Fragments.SearchFragment;
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.common.data.DataBufferUtils;
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.Places;
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;

/**
 * Created by anuj.sharma on 4/6/2016.
 */
public class PlaceAutocompleteAdapter extends RecyclerView.Adapter<PlaceAutocompleteAdapter.PlaceViewHolder> implements Filterable{

    public interface PlaceAutoCompleteInterface{
        public void onPlaceClick(ArrayList<PlaceAutocomplete> mResultList, int position);
    }

    Context mContext;
    PlaceAutoCompleteInterface mListener;
    private static final String TAG = "PlaceAutocompleteAdapter";
    private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
    ArrayList<PlaceAutocomplete> mResultList;

    private GoogleApiClient mGoogleApiClient;

    private LatLngBounds mBounds;

    private int layout;

    private AutocompleteFilter mPlaceFilter;


    public PlaceAutocompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
                                    LatLngBounds bounds, AutocompleteFilter filter){
        this.mContext = context;
        layout = resource;
        mGoogleApiClient = googleApiClient;
        mBounds = bounds;
        mPlaceFilter = filter;
        this.mListener = (PlaceAutoCompleteInterface)mContext;
    }

    /*
    Clear List items
     */
    public void clearList(){
        if(mResultList!=null && mResultList.size()>0){
            mResultList.clear();
        }
    }


    /**
     * Sets the bounds for all subsequent queries.
     */
    public void setBounds(LatLngBounds bounds) {
        mBounds = bounds;
    }

    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            @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.
                    mResultList = getAutocomplete(constraint);
                    if (mResultList != null) {
                        // The API successfully returned results.
                        results.values = mResultList;
                        results.count = mResultList.size();
                    }
                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.count > 0) {
                    // The API returned at least one result, update the data.
                    notifyDataSetChanged();
                } else {
                    // The API did not return any results, invalidate the data set.
                    //notifyDataSetInvalidated();
                }
            }
        };
        return filter;
    }

    private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
        if (mGoogleApiClient.isConnected()) {
            Log.i("", "Starting autocomplete query for: " + constraint);

            // 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(),
                                    mBounds, mPlaceFilter);

            // 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 resultList = new ArrayList<>(autocompletePredictions.getCount());
            while (iterator.hasNext()) {
                AutocompletePrediction prediction = iterator.next();
                // Get the details of this prediction and copy it into a new PlaceAutocomplete object.
                resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
                        prediction.getDescription()));
            }

            // 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;
    }

    @Override
    public PlaceViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View convertView = layoutInflater.inflate(layout, viewGroup, false);
        PlaceViewHolder mPredictionHolder = new PlaceViewHolder(convertView);
        return mPredictionHolder;
    }


    @Override
    public void onBindViewHolder(PlaceViewHolder mPredictionHolder, final int i) {
        mPredictionHolder.mAddress.setText(mResultList.get(i).description);

        mPredictionHolder.mParentLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onPlaceClick(mResultList,i);
            }
        });

    }

    @Override
    public int getItemCount() {
        if(mResultList != null)
            return mResultList.size();
        else
            return 0;
    }

    public PlaceAutocomplete getItem(int position) {
        return mResultList.get(position);
    }

    /*
    View Holder For Trip History
     */
    public class PlaceViewHolder extends RecyclerView.ViewHolder {
        //        CardView mCardView;
        public RelativeLayout mParentLayout;
        public TextView mAddress;

        public PlaceViewHolder(View itemView) {
            super(itemView);
            mParentLayout = (RelativeLayout)itemView.findViewById(R.id.predictedRow);
            mAddress = (TextView)itemView.findViewById(R.id.address);
        }

    }

    /**
     * Holder for Places Geo Data Autocomplete API results.
     */
    public class PlaceAutocomplete {

        public CharSequence placeId;
        public CharSequence description;

        PlaceAutocomplete(CharSequence placeId, CharSequence description) {
            this.placeId = placeId;
            this.description = description;
        }

        @Override
        public String toString() {
            return description.toString();
        }
    }
}

view_placesearch.xml

アダプターに表示するカスタマイズされたビュー

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/predictedRow"
    Android:layout_width="match_parent"
    Android:layout_height="65dp"
    Android:layout_marginLeft="10dp"
    Android:layout_marginRight="10dp"
    Android:layout_centerVertical="true"
    Android:gravity="center_vertical">

    <ImageView
        Android:id="@+id/image"
        Android:layout_width="22dp"
        Android:layout_height="22dp"
        Android:src="@drawable/ic_action_navigate"
        Android:layout_marginLeft="10dp"
        Android:layout_marginTop="20dp"
        />

    <TextView
        Android:id="@+id/address"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textColor="#000"
        Android:textSize="15sp"
        Android:layout_toRightOf="@+id/image"
        Android:layout_centerVertical="true"
        Android:layout_marginLeft="20dp"
        Android:layout_marginRight="20dp"
        />
<View
    Android:layout_width="match_parent"
    Android:layout_height="1dp"
    Android:background="@color/light_gray"
    Android:layout_alignParentBottom="true"/>
</RelativeLayout>

それがあなたにも役立つことを願っています。

注:manifestファイルにAPIキーを追加することを忘れないでください。

出力は次のようになります:

enter image description here

役立つリンクがいくつか見つかりました。

1。Androidカスタムアダプターを使用したPlat Places

44
Anuj Sharma

kotlin:

fun queryPlaces(text: String) {
    val task = object : AsyncTask<Void,Void,Void>(){
        override fun doInBackground(vararg params: Void?): Void? {
            val results = Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, text, null, null)
            val autocompletePredictions = results.await()
            val iterator = autocompletePredictions.iterator()
            while (iterator.hasNext()) {
                val prediction = iterator.next()
                println("PlaceId:${prediction.placeId}")
                println("PrimaryText:${prediction.getPrimaryText(null)}")
            }
            autocompletePredictions.release()
            return null
        }
    }
    task.execute()
}

場所の詳細を取得する場合:

fun queryPlaces(text: String) {
    val geoDataClient : GeoDataClient = Places.getGeoDataClient(context!!)

    val task = object : AsyncTask<Void,Void,Void>(){
        override fun doInBackground(vararg params: Void?): Void? {
            val results = Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, text, null, null)
            val autocompletePredictions = results.await()
            val iterator = autocompletePredictions.iterator()
            while (iterator.hasNext()) {
                val prediction = iterator.next()

                geoDataClient.getPlaceById(prediction.placeId).addOnCompleteListener {task->
                    val places = task.result
                    val myPlace = places?.get(0)
                    println("name:${myPlace?.name}")
                    println("latLng:${myPlace?.latLng}")
                    println("address:${myPlace?.address}")
                }
            }
            autocompletePredictions.release()
            return null
        }
    }
    task.execute()
}
1
AnsonChen

AutocompletePrediction APIの最新の変更を考慮して、修正されたアダプターとフィルターのコードを以下に示します。

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;
    }

}
1

フィルターオブジェクトで毎回新しいarraylistを作成する必要があります

@Override 
public Filter getFilter() {
    Filter filter = new Filter() {
        @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. 

               /**You just need to create new object then crash problem 
                 will not occur**/
                mResultList = new ArrayList<>;

                mResultList = getAutocomplete(constraint);
                if (mResultList != null) {
                    // The API successfully returned results. 
                    results.values = mResultList;
                    results.count = mResultList.size();
                } 
            } 
            return results;
        } 

        @Override 
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                // The API returned at least one result, update the data. 
                notifyDataSetChanged(); 
            } else { 
                // The API did not return any results, invalidate the data set. 
                //notifyDataSetInvalidated(); 
            } 
        } 
    }; 
    return filter;
} 
0
Raj Kumar