[英]Android Place Autocomplete Fragment: Unable to set text
谷歌最近更新了他們的安卓版 Places SDK,所以現在我也在更新我的代碼。 我正在嘗試使用AutocompleteSupportFragment
來允許用戶設置他們的地址。
這是我的代碼:
mAddressEditText = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.address);
mAddressEditText.setPlaceFields(Arrays.asList(Place.Field.ADDRESS, Place.Field.LAT_LNG));
mAddressEditText.setHint("Address");
mAddressEditText.setText("Test1"); // Works fine at the beginning, disappears after selecting a place and shows only the hint
mAddressEditText.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
Log.d(TAG, "Place Selected");
// Other Stuff
mAddressEditText.setText("Test2"); // Doesn't Work, all I can see is the hint
mAddressEditText.setText(place.getAddress()); // Doesn't Work, all I can see is the hint
}
@Override
public void onError(Status status) {
Log.e(TAG, "An error occurred: " + status);
invalidAddressDialog.show();
}
});
在之前的 SDK 中,片段會自動將文本設置為所選地址。 這在新的 SDK 中不起作用(不確定這是否是故意的)。 所以我試圖手動設置它。 正如您在我的代碼的注釋中看到的那樣,在偵聽器之外使用setText
工作正常。 在聽眾內部,他們沒有。
我做錯了什么還是這是一個錯誤?
編輯:這么長時間,我仍然無法解決這個問題。 完全清楚,我可以從片段中正確獲取地址,唯一不起作用的是setText
。
然而,由於一些答案表明他們沒有遇到同樣的問題,我開始認為這可能與我使用的庫版本有關?
這些是我在build.gradle
中的庫:
api 'com.android.support:appcompat-v7:28.0.0'
api 'com.android.support:support-annotations:28.0.0'
api 'com.android.support:multidex:1.0.3'
api 'com.google.firebase:firebase-core:16.0.8'
api 'com.google.firebase:firebase-auth:16.2.1'
api 'com.google.firebase:firebase-firestore:18.2.0'
api 'com.google.firebase:firebase-storage:16.1.0'
api 'com.google.android.libraries.places:places:1.1.0'
setText 一直給我同樣的問題 - 我認為這一定是一個錯誤。 但是,我發現了一些提示。 在您的 onPlaceSelected 中,您可以輸入以下內容:
爪哇
EditText etPlace = (EditText) autocompleteFragment.getView().findViewById(R.id.places_autocomplete_search_input);
etPlace.setHint(place.getAddress())
科特林
val etPlace = autocompleteFragment.view?.findViewById(R.id.places_autocomplete_search_input) as EditText
etPlace.hint = place.address
這是我正在使用的代碼,它運行良好。
對 build.gradle(應用級別)進行一些更改
將此添加到 build.gradle:
android{
...
ext {
googlePlayServicesVersion = "15.0.1"
}
}
添加這些依賴項:
dependencies {
...
//Also if you're using any firebase dependencies make sure that the are up to date
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.libraries.places:places:1.1.0'
}
apply plugin: 'com.google.gms.google-services'
在 xml 布局中:
<fragment
android:id="@+id/autocomplete_fragment"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
活動中的代碼:
private void initGooglePlacesApi() {
// Initialize Places.
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(getApplicationContext());
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setHint(getString(R.string.select_location_search_bar));
// autocompleteFragment.setLocationRestriction(RectangularBounds.newInstance(
// new LatLng(34.7006096, 19.2477876),
// new LatLng(41.7488862, 29.7296986))); //Greece bounds
autocompleteFragment.setCountry("gr");
// Specify the types of place data to return.
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ADDRESS, Place.Field.ADDRESS_COMPONENTS));
autocompleteFragment.setTypeFilter(TypeFilter.ADDRESS);
// Set up a PlaceSelectionListener to handle the response.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
if(place.getAddressComponents().asList().get(0).getTypes().get(0).equalsIgnoreCase("route")){
binding.textViewLocation.setText(place.getAddress()); //Works well
location = place.getAddress();
}else{ //If user does not choose a specific place.
AndroidUtils.vibratePhone(getApplication(), 200);
TastyToast.makeText(getApplicationContext(),
getString(R.string.choose_an_address), TastyToast.DEFAULT, TastyToast.CONFUSING);
}
Log.i(TAG, "Place: " + place.getAddressComponents().asList().get(0).getTypes().get(0) + ", " + place.getId() + ", " + place.getAddress());
}
@Override
public void onError(Status status) {
Log.i(TAG, "An error occurred: " + status);
}
});
}
我找到了一個非常簡單的解決方案……只是在您在 EditText 中設置文本的那一刻延遲一點。 因此,在您的 PlaceSelectionListener 中,只需這樣做:
Handler().postDelayed({
mAddressEditText.setText(place.getAddress());
}, 300)
PS:這是 kotlin 代碼,但它在 Java 中幾乎相似
我相信這是一個錯誤,因為讓它像這樣工作是沒有意義的。 有效的是設置其他自動完成的文本而不是它自己的文本。 這一定是個bug。
編輯:這是我更新的答案
# When you are using AutocompleteSupportFragment or AutocompleteActivity
# in Fragments, do this:
public class YourFragment extends Fragment {
/.../
@Override
public void onActivityResult (int requestCode,int resultCode,
@Nullable Intent data){
# AUTOCOMPLETE_REQUEST_CODE is just a unique constant, define it
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == AutocompleteActivity.RESULT_OK) {
Place place = Autocomplete.getPlaceFromIntent(data);
// when resultcode is RESULT_OK
mAddressEditText.setText(place.getName());
// Notice this line, update your editText up here
}else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
Status status = Autocomplete.getStatusFromIntent(data);
// Handle error
} else if (resultCode == AutocompleteActivity.RESULT_CANCELED) {
// Handle results if canceled
}
super.onActivityResult(requestCode, resultCode, data);
}
}
/.../
}
# If you are extending AppCompatActivity, you might want to do this
# ONLY when you are already doing something in onActivityResult
public class YourActivity extends AppCompatActivity{
/.../
@Override
public void onActivityResult (int requestCode,int resultCode,@Nullable Intent data){
# your logic here.
/.../
# if you are already overriding onActivityResult,
# do not forget to put this line
super.onActivityResult(requestCode, resultCode, data);
}
/.../
}
我也遇到了這個問題。 原來你不得不覆蓋這個反正實現它,無論是使用AutocompleteSupportFragment
或AutocompleteActivity
如果您在碎片工作。
如果你正在使用AppCompatActivity
你不必實現它,但如果你已經覆蓋onActivityResult
做某事,不要忘記調用基本方法super.onActivityResult
獲取 AutoCompleteFragment 的引用,然后將文本設置為自動完成片段,如
autoCompleteFragment.setText("Address")
作為參考,您可以查看文檔
我嘗試了CacheMeOutside 的解決方案,但它根本不起作用。 所以,我決定嘗試Matthias 的解決方案並且它確實有效,因為文本實際上設置然后由於某種原因立即刪除。 一個小的延遲修復它。 延遲可以小到 1 毫秒。
如果我的解決方案對您不起作用,您可以嘗試嘗試延遲。 它似乎也不會停止視圖渲染,因此您可以隨時設置。
private lateinit var autocomplete: AutocompleteSupportFragment
override fun onPlaceSelected(place: Place) {
Timer("SetAddress", false).schedule(1) {
autocomplete.setText(place.address)
}
}
Kotlin 中的代碼片段。 如果您的代碼是 Java 語言,只需找一些工具將代碼執行延遲一段時間即可。
Matthias 的解決方案正在起作用,但它在 kotlin 中。 下面是 Java 中的相同實現
@Override
public void onPlaceSelected(Place place) {
String name = place.getName()+", "+place.getAddress();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
autocompleteFragmentDestination.setText(name);
}
},300);
}
簡單的。 使用 Spannable 字符串設置顏色!
val autocompleteFragment = childFragmentManager.findFragmentById(R.id.location_filter_autocomplete) as AutocompleteSupportFragment
val text = SpannableString("Enter a location")
text.setSpan(ForegroundColorSpan(Color.BLACK), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
autocompleteFragment.setHint(text)
在 onPlaceSelectedListener() 里面做同樣的事情
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.