Intereting Posts
ОШИБКА: Android Source Generator: Файл AndroidManifest.xml не найден Сенсорное обнаружение на полилинии в Google Maps API Android v2 Вызывая ошибку java.IllegalStateException, No Activity, только при навигации по фрагменту для SECOND time Как использовать API входа в Google с помощью Cordova / Phonegap Уведомления о состоянии панели Android – намерение во второй раз получить старые дополнительные функции Android: Ошибка установки: INSTALL_FAILED_INSUFFICIENT_STORAGE Android JSONObject против GSON Android – Как запустить Google Map в Android-приложении с определенным местоположением, уровнем масштабирования и маркером Как объекты Java размещаются в памяти на Android? Styling EditText view с формой, способной выглядеть похожей на новую голографическую тему для Android <3.0 Обработка пробелов в logcat Как сохранить изображение в галерее Android Ошибка: не удается открыть файл класса R.java Open failed: EACCES (разрешение отклонено) Как работает репозиторий манифеста репозитория Android?

Как настроить диалоговое окно виджета PlaceAutocomplete для списка мест

Мне нужно показать список мест в dropdown списке, используя google placeAutocomplete widgets. Здесь я получаю диалог, чтобы показывать места в соответствии с моим запросом, но мне нужно предоставить собственный дизайн для этого диалогового окна результатов поиска, как в приложениях Uber, Ola. Здесь мне нужен дизайн, как показано ниже. Если кто-то сделал это раньше, пожалуйста, дайте мне свои предложения, спасибо заранее.

Введите описание изображения здесь

Solutions Collecting From Web of "Как настроить диалоговое окно виджета PlaceAutocomplete для списка мест"

Вам нужно настроить адаптер. Я реализовал эту функцию в своем проекте. Вы можете следовать этому.

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> 1 <?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> 

Надеюсь, это вам тоже поможет.

Примечание. Не забудьте добавить ключ API в файл manifest .

Результат будет выглядеть следующим образом:

Введите описание изображения здесь

Я нашел некоторые полезные ссылки, которые также могут помочь вам.

1. Android Plat Places с использованием пользовательского адаптера

 you just need to create new arraylist every time in filter object @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; }