Kotlin:无法调用表达式,因为未找到函数invoke() [英] Kotlin: Expression can't be invoked because function invoke() is not found

查看:446
本文介绍了Kotlin:无法调用表达式,因为未找到函数invoke()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个用于实现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" -> ...

letalso结合使用甚至可以进一步减少您的代码,但这可能是另一个故事,更适合代码评论.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆