Kotlin:无法调用表达式,因为未找到函数invoke() [英] Kotlin: Expression can't be invoked because function invoke() is not found
问题描述
我正在尝试构建一个用于实现Google地图的应用.由于某种原因,我收到错误消息,因为找不到函数invoke(),因此无法调用表达式.我不知道如何解决这个问题,也许你们中的一个可以帮助您?
I'm trying to build an app where I implement Google maps. for some reason I get the error that the expression can't be invoked because the function invoke() is not found. I don't know how to fix this maybe one of you guys can help?
package com.example.maxs.kotlinnearbyv2
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.example.maxs.kotlinnearbyv2.Common.Common
import com.example.maxs.kotlinnearbyv2.Model.MyPlaces
import com.example.maxs.kotlinnearbyv2.Remote.IGoogleAPIService
import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import kotlinx.android.synthetic.main.activity_maps.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
private var latitude:Double=0.toDouble()
private var longitude:Double=0.toDouble()
lateinit var mService:IGoogleAPIService
internal var currentPlace: MyPlaces?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
//Init Service
mService = Common.googleApiService
bottom_navigation_view.setOnNavigationItemReselectedListener {item ->
when(item.itemId)
{
R.id.action_hospital -> nearByPlace("hospital")
R.id.action_restaurant -> nearByPlace("restaurant")
R.id.action_market -> nearByPlace("market")
R.id.action_school -> nearByPlace("school")
}
}
}
private fun nearByPlace(typePlace: String) {
//Clear all marker on Map
mMap.clear()
//build URL request base on location
val url = getUrl(latitude,longitude, typePlace)
mService.getNearByPlaces(url)
.enqueue(object : Callback<MyPlaces>{
override fun onResponse(call: Call<MyPlaces>, response: Response<MyPlaces>) {
currentPlace = response.body()
if(response!!.isSuccessful)
{
for(i in 0 until response!!.body()!!.results!!.size)
{
val markerOptions=MarkerOptions()
val googlePlace = response.body().results!!(i)
val lat = googlePlace.geometry!!.location!!.lat
val lng = googlePlace.geometry!!.location!!.lng
val placeName = googlePlace.name
val latLng = LatLng(lat, lng)
markerOptions.position(latLng)
markerOptions.title(placeName)
if (typePlace.equals("hospital"))
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_local_hospital_black_24dp))
else if (typePlace.equals("market"))
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_shopping_cart_black_24dp))
else if (typePlace.equals("restaurant"))
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_restaurant_black_24dp))
else if (typePlace.equals("school"))
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_school_black_24dp))
else
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
markerOptions.snippet(i.toString())
//add marker to map
mMap!!.addMarker(markerOptions)
}
//move camera
mMap!!.moveCamera(CameraUpdateFactory.newLatLng(LatLng(latitude, longitude)))
mMap!!.animateCamera(CameraUpdateFactory.zoomTo(15.0f))
}
}
override fun onFailure(call: Call<MyPlaces>, t: Throwable) {
Toast.makeText(baseContext, ""+t!!.message,Toast.LENGTH_SHORT).show()
}
})
}
private fun getUrl(latitude: Double, longitude: Double, typePlace: String): String {
val googlePlaceUrl = StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json")
googlePlaceUrl.append("?location=$latitude,$longitude")
googlePlaceUrl.append("&radius=10000") //10 km
googlePlaceUrl.append("&type=$typePlace")
googlePlaceUrl.append("&key=")
Log.d("URL_DEBUG", googlePlaceUrl.toString())
return googlePlaceUrl.toString()
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val barbier = LatLng(52.391274, 6.449712)
mMap.addMarker(MarkerOptions().position(barbier).title("Marker in Barbier"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(barbier))
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(barbier, 15.0f))
}
}
我似乎找不到任何解决方案,我可能想办法很难… 错误出现在response.body()!!.results !!(i)
I can't seem to find any solution and i'm probably think way to difficult… the error is giving at the response.body()!!.results!!(i)
val googlePlace = response.body().results!!(i)
肯定现在让我发疯了.
推荐答案
要访问数组或列表中的元素,请使用方括号,例如:
To access an element in an array or list, use square brackets, e.g.:
array[i]
list[i] // or list.get(i)
results!![i]
关于错误消息:Kotlin假定调用操作符 ,您没有提供.您可能需要阅读invoke-operator的优点.有时它非常方便.但是对于您的问题,方括号就足够了.
Regarding the error message: Kotlin was assuming an invoke operator, which you didn't supply. You may want to read what an invoke-operator is good for. Sometimes it comes in very handy. But for your problem the square brackets should suffice.
作为(更多)补充说明:不要用大量的!!
编写代码,而是首先尝试确定null
可能是什么,并在不适合您的情况下忽略其余的内容需求,例如:
As a (further) side-note: don't write your code with tons of !!
, rather try to identify what can be null
in the first place and omit the rest if it doesn't suit your needs, e.g.:
response?.also {
if (it.isSuccessful) {
it.body()?.results?.forEach {
//...
}
}
}
只是一个开始...您可能然后想进一步简化事情...只要可能就省略!!
...您可能还想阅读有关智能类型转换.
Just a start... you may then want to simplify things even more... Just omit !!
whenever possible... You may also want to read about null safety in Kotlin and maybe also about the smart casts.
您的typePlace.equals(...
-条件也可以完全替换为 c4> ,例如:
Your typePlace.equals(...
-conditions can also perfectly be replaced with when
, e.g.:
when(typePlace) {
"hospital" -> ...
"market" -> ...
与let
或also
结合使用甚至可以进一步减少您的代码,但这可能是另一个故事,更适合代码评论.
That combined with either let
or also
may even further reduce your code, but that will probably be another story, better suited for code review.
这篇关于Kotlin:无法调用表达式,因为未找到函数invoke()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!