Как мне сделать, чтобы placeRequest принял первый результат прогнозов? - PullRequest
0 голосов
/ 19 января 2020

Я должен передать первый результат (индекс 0), который я получаю от findAutocompletePredictions(userInputRequest) к placeRequest, но я не могу получить доступ к predictions, так как он объявлен внутри addOnSuccessListener, и если я пытаюсь иметь глобальное свойство и передать его в placeRequest, поскольку findAutocompletePredictions имеет асин c, это глобальное свойство будет либо нулевым, либо значением инициализации при передаче в placeRequest

class PlacesApi(context: Context, apiKey: String) {

    private val placesClient: PlacesClient
    private val token: AutocompleteSessionToken
    private lateinit var place: Place

    init {
        Places.initialize(context, apiKey)
        placesClient = Places.createClient(context)
        token = AutocompleteSessionToken.newInstance()
    }

    fun getCityPlaceId(inputString: String) {

        val userInputRequest = FindAutocompletePredictionsRequest.builder()
            .setTypeFilter(TypeFilter.CITIES)
            .setSessionToken(token)
            .setQuery(inputString)
            .build()

        placesClient.findAutocompletePredictions(userInputRequest)
            .addOnSuccessListener { response: FindAutocompletePredictionsResponse ->

                for (prediction in response.autocompletePredictions) {

                    Log.d("Place ID", prediction.placeId)
                    Log.d("Place City", prediction.getPrimaryText(null).toString())
                    Log.d("Place Country", prediction.getSecondaryText(null).toString())
                }
            }

        val placeFields: List<Place.Field> =
            listOf(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG)

        // I need to change this hard-coded string value to the fist result of the predictions
        val placeRequest = FetchPlaceRequest.newInstance("ChIJD7fiBh9u5kcRYJSMaMOCCwQ", placeFields)

        placesClient.fetchPlace(placeRequest)
            .addOnSuccessListener { fetchPlaceResponse: FetchPlaceResponse ->
                place = fetchPlaceResponse.place
                Log.i("Place coordinates: ", place.latLng?.longitude.toString())
                Log.i("Place coordinates: ", place.latLng?.latitude.toString())
                Log.i("Place name: ", place.name.toString())
                Log.i("Place address: ", place.address.toString())
            }.addOnFailureListener {
                if (it is ApiException) {
                    Log.e("Place not found", "Place not found " + it.message)
                }
            }
    }
}

1 Ответ

1 голос
/ 19 января 2020

Поскольку findAutocompletePredictions - это Asyn c, нет смысла выполнять placesClient.fetchPlace до того, как станет доступен результат из findAutocompletePredictions.

Что вам нужно сделать, так это onSuccess или findAutocompletePredictions вызвать другую функцию и передайте ему результат findAutocompletePredictions, тогда вторая функция может получить место для вас

fun getCityPlaceId(inputString: String) {

    val userInputRequest = FindAutocompletePredictionsRequest.builder()
        .setTypeFilter(TypeFilter.CITIES)
        .setSessionToken(token)
        .setQuery(inputString)
        .build()

    // on success pass the result to another function which can 
    // take care of fetching the place information
    // you can pass entire result or the only part required to get place info
    placesClient.findAutocompletePredictions(userInputRequest)
          .addOnSuccessListener { fetchPlace(it) } 

}

private fun fetchPlace(response: FindAutocompletePredictionsResponse){
    val placeFields: List<Place.Field> =
        listOf(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG)
    val placeRequest = FetchPlaceRequest.newInstance(response.autocompletePredictions[0].placeId, placeFields)

    placesClient.fetchPlace(placeRequest)
        .addOnSuccessListener { fetchPlaceResponse: FetchPlaceResponse ->
            place = fetchPlaceResponse.place
            Log.i("Place coordinates: ", place.latLng?.longitude.toString())
            Log.i("Place coordinates: ", place.latLng?.latitude.toString())
            Log.i("Place name: ", place.name.toString())
            Log.i("Place address: ", place.address.toString())
        }.addOnFailureListener {
            if (it is ApiException) {
                Log.e("Place not found", "Place not found " + it.message)
            }
        }
}
...