7

Google 最近更新了他们的 Places SDK for android,所以现在我也在更新我的代码。我正在尝试使用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 中,fragment 会自动将文本设置为选定的地址。这在新的 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'
4

9 回答 9

8

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
于 2019-04-10T11:51:35.323 回答
4

这是我正在使用的代码,它运行良好。

对 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);
            }
        });
    }
于 2019-04-28T15:20:07.337 回答
1

我找到了一个非常简单的解决方案......只是在您在 EditText 中设置文本的那一刻延迟一点。所以在你的 PlaceSelectionListener 中这样做:

Handler().postDelayed({
    mAddressEditText.setText(place.getAddress());
}, 300)

PS:这是 kotlin 代码,但在 Java 中几乎相似

于 2019-08-09T05:42:50.473 回答
0

编辑:这是我更新的答案

# 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);
 }
/.../
}

我也遇到了问题。事实证明,无论是使用还是在 Fragments 中工作,您都必须覆盖它并实现它。AutocompleteSupportFragmentAutocompleteActivity

如果您正在使用AppCompatActivity,则不必实现它,但如果您已经onActivityResult在做某事,请不要忘记调用基本方法super.onActivityResult

于 2019-04-28T13:34:59.843 回答
0

我尝试了 CacheMeOutside 的解决方案,但它根本不起作用。因此,我决定尝试Matthias 的解决方案,它确实有效,因为文本实际设置,然后由于某种原因立即删除。一个小的延迟修复它。延迟可以小至 1 毫秒。

如果我的解决方案对您不起作用,您可以尝试尝试延迟。它似乎也不会停止视图渲染,因此您可以随时设置。

private lateinit var autocomplete: AutocompleteSupportFragment

        override fun onPlaceSelected(place: Place) {
            Timer("SetAddress", false).schedule(1) {
                autocomplete.setText(place.address)
            }
        }

Kotlin 中的代码片段。如果您的代码是用 Java 编写的,只需找到一些工具来延迟代码执行一段时间。

于 2020-02-07T08:18:58.690 回答
0

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

                    }
于 2020-08-03T13:23:16.497 回答
0

简单的。使用 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() 里面做同样的事情

于 2021-07-23T03:41:18.333 回答
0

获取 AutoCompleteFragment 的引用,然后将文本设置为自动完成片段,例如

autoCompleteFragment.setText("Address")

作为参考,您可以查看文档

https://developers.google.com/android/reference/com/google/android/gms/location/places/ui/PlaceAutocompleteFragment

于 2019-09-04T04:25:27.037 回答
0

我相信这是一个错误,因为让它像这样工作是没有意义的。起作用的是设置其他自动完成的文本,而不是它自己的文本。这必须是一个错误。

于 2019-02-28T00:02:27.687 回答