How to implement google places autocomplete programmatically

后端 未结 4 713
情歌与酒
情歌与酒 2020-12-29 09:44

Autocomplete predictions don\'t show up in my MapsActivity when i type text in AutoCompleteTextView (mSearchText).

I tried following the tutorial at the following li

4条回答
  •  灰色年华
    2020-12-29 10:38

    In Kotlin

    1. activity layout file

      
      
      
      
      
          
      
      
      
    2. In Activity

      class MainActivity :AppCompatActivity(), OnMapReadyCallback {
      
      private var mMap: GoogleMap? = null
      private var placeAdapter: PlaceArrayAdapter? = null
      private lateinit var mPlacesClient: PlacesClient
      
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
      }
      
      override fun onPostCreate(savedInstanceState: Bundle?) {
          super.onPostCreate(savedInstanceState)
      
          Places.initialize(this, "GOOGLE_MAPS_KEY")
          mPlacesClient = Places.createClient(this)
      
          val mapFragment: SupportMapFragment? = supportFragmentManager.findFragmentById(R.id.mapLocation) as? SupportMapFragment
          mapFragment?.getMapAsync(this)
      
          placeAdapter = PlaceArrayAdapter(this, R.layout.layout_item_places, mPlacesClient)
          autoCompleteEditText.setAdapter(placeAdapter)
      
          autoCompleteEditText.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
              val place = parent.getItemAtPosition(position) as PlaceDataModel
              autoCompleteEditText.apply {
                  setText(place.fullText)
                  setSelection(autoCompleteEditText.length())
              }
          }
      }
      
      override fun onMapReady(p0: GoogleMap?) {
      
      }
      }
      
    3. PlaceArrayAdapter

      class PlaceArrayAdapter(context: Context,val resource: Int, val mPlacesClient: PlacesClient) : ArrayAdapter(context, resource), Filterable {
      
      private var mContext : Context = context
      private var resultList = arrayListOf()
      
      override fun getCount(): Int {
          return when {
              resultList.isNullOrEmpty() -> 0
              else -> resultList.size
          }
      }
      
      override fun getItem(position: Int): PlaceDataModel? {
          return when {
              resultList.isNullOrEmpty() -> null
              else -> resultList[position]
          }
      }
      
      override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
          var view = convertView
          val viewHolder: ViewHolder
          if (view == null) {
              viewHolder = ViewHolder()
              view = LayoutInflater.from(context).inflate(resource, parent, false)
              viewHolder.description = view.findViewById(R.id.searchFullText) as TextView
              view.tag = viewHolder
          } else {
              viewHolder = view.tag as ViewHolder
          }
          bindView(viewHolder, resultList, position)
          return view!!
      }
      
      private fun bindView(viewHolder: ViewHolder, place: ArrayList, position: Int) {
          if (!place.isNullOrEmpty()) {
              viewHolder.description?.text = place[position].fullText
          }
      }
      
      override fun getFilter(): Filter {
          return object : Filter() {
              override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                  if (results != null && results.count > 0) {
                      mContext.runOnUiThread {
                          notifyDataSetChanged()
                      }
                  } else {
                      notifyDataSetInvalidated()
                  }
              }
      
              override fun performFiltering(constraint: CharSequence?): FilterResults {
                  val filterResults = FilterResults()
                  if (constraint != null) {
                      resultList.clear()
                      val address = getAutocomplete(mPlacesClient, constraint.toString())
                      address?.let {
                          for (i in address.indices) {
                              val item = address[i]
                              resultList.add(PlaceDataModel(item.placeId, item.getFullText(StyleSpan(Typeface.BOLD)).toString()))
                          }
                      }
                      filterResults.values = resultList
                      filterResults.count = resultList.size
                  }
                  return filterResults
              }
          }
      }
      
      internal class ViewHolder {
          var description: TextView? = null
      }
      }
      
    4. getAutocomplete method (you can add in adapter or extention)

      fun getAutocomplete(mPlacesClient: PlacesClient, constraint: CharSequence): List {
        var list = listOf()
        val token = AutocompleteSessionToken.newInstance()
        val request = FindAutocompletePredictionsRequest.builder().setTypeFilter(TypeFilter.ADDRESS).setSessionToken(token).setQuery(constraint.toString()).build()
        val prediction = mPlacesClient.findAutocompletePredictions(request)
        try {
            Tasks.await(prediction, TASK_AWAIT, TimeUnit.SECONDS)
        } catch (e: ExecutionException) {
            e.printStackTrace()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        } catch (e: TimeoutException) {
            e.printStackTrace()
        }
      
        if (prediction.isSuccessful) {
            val findAutocompletePredictionsResponse = prediction.result
          findAutocompletePredictionsResponse?.let {
                list = findAutocompletePredictionsResponse.autocompletePredictions
            }
            return list
        }
        return list
      }
      
    5. R.layout.layout_item_places

      
      
      
      

    Github demo

提交回复
热议问题