我正在GoogleApiClient
使用Places.GEO_DATA_API
api在AutoCompleteTextView
中搜索时获取地点列表。地方正在变得很好,我只需要打印AutoCompleteTextView
中选择的地点。我使用了OnItemClickListener
并且它引发了一些错误。你能帮我打印一下从AutoCompleteTextView
中选出的地方吗?有没有简单的方法来打印所选的地名?
我的班级文件
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.enableAutoManage(getActivity(), 200 /* clientId */, this)
.addApi(Places.GEO_DATA_API)
.build();
ac_location.setAdapter(new PlaceAutocompleteAdapter(getActivity(), mGoogleApiClient, null, null));
我的适配器
package grocery.iroid.com.grocery.ui.main.location.adapter;
import android.content.Context;
import android.graphics.Typeface;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
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.concurrent.TimeUnit;
import grocery.iroid.com.grocery.R;
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
private ArrayList<AutocompletePrediction> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* @see ArrayAdapter#ArrayAdapter(Context, int)
*/
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
//super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
super(context, R.layout.row_place_auto_complete, R.id.tvPlace);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
@Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
@Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(R.id.tvPlace);
TextView textView2 = (TextView) row.findViewById(R.id.tvCountry);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
/**
* Returns the filter for the current set of autocomplete results.
*/
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We need a separate list to store the results, since
// this is run asynchronously.
ArrayList<AutocompletePrediction> filterData = new ArrayList<>();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
filterData = getAutocomplete(constraint);
}
results.values = filterData;
if (filterData != null) {
results.count = filterData.size();
} else {
results.count = 0;
}
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.
mResultList = (ArrayList<AutocompletePrediction>) results.values;
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
@Override
public CharSequence convertResultToString(Object resultValue) {
// Override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* objects to store the Place ID and description that the API returns.
* Returns an empty list if no results were found.
* Returns null if the API client is not available or the query did not complete
* successfully.
* This method MUST be called off the main UI thread, as it will block until data is returned
* from the API, which may include a network request.
*
* @param constraint Autocomplete query string
* @return Results from the autocomplete API or null if the query was not successful.
* @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
* @see AutocompletePrediction#freeze()
*/
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
// Log.i(TAG, "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(),
null/*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(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
// Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
// Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
// + " predictions.");
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
// Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}
错误当我尝试打印地点时
ac_location.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Get data associated with the specified position
// in the list (AdapterView)
String description = (String) parent.getItemAtPosition(position);
Toast.makeText(getActivity(), description, Toast.LENGTH_SHORT).show();
}
});
Logcat
01-11 10:45:06.967 3527-3527/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: grocery.iroid.com.grocery, PID: 3527
java.lang.ClassCastException: com.google.android.gms.location.places.internal.zza cannot be cast to java.lang.String
at grocery.iroid.com.grocery.ui.main.location.LocationResultFragment$2.onItemClick(LocationResultFragment.java:169)
at android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:906)
at android.widget.AutoCompleteTextView.-wrap1(AutoCompleteTextView.java)
at android.widget.AutoCompleteTextView$DropDownItemClickListener.onItemClick(AutoCompleteTextView.java:1202)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3042)
at android.widget.AbsListView$3.run(AbsListView.java:3879)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:3)
我通过创建回调来实现这一点,因为我必须在不同的地方使用它,您可以根据您的要求更改此代码,我可以从上面的适配器获取地点详细信息。
// CallBack implement this callback to get place details
public interface OnAutoLocationItemClickListner {
public void onAutoLocationItemClicked(String addr, double Lat, double longitutde);
}
private AutoCompleteTextView autoCompleteTextView;
private PlaceAutocompleteAdapter mAdapter;
autoCompleteTextView = findViewById(R.id.autoCompleteTextView);
mAdapter = new PlaceAutocompleteAdapter(activity, mGoogleApiClient, null);
autoCompleteTextView.setAdapter(mAdapter);
autoCompleteTextView.setOnItemClickListener(mAutocompleteClickListener);
private AdapterView.OnItemClickListener mAutocompleteClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final AutocompletePrediction item = mAdapter.getItem(position);
if (item != null) {
final String placeId = item.getPlaceId();
final CharSequence primaryText = item.getPrimaryText(null);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(PlaceBuffer places) {
try {
if (places.getStatus().isSuccess() && places.getCount() > 0) {
final Place myPlace = places.get(0);
if (listner != null)
isClicked = true;
listner.onAutoLocationItemClicked(myPlace.getAddress().toString(), myPlace.getLatLng().latitude, myPlace.getLatLng().longitude);
Log.e("Place found: ", "" + myPlace.getName());
// here you will get place string and its respective latitude and longitude
} else {
Log.e("Place not found", "");
ToastUtil.showShortToast("Error getting details of this address");
}
places.release();
} catch (Exception e) {
e.printStackTrace();
}
}
};