lateinit值始终为null或未使用MapBox初始化

时间:2018-08-15 16:38:45

标签: android-fragments kotlin mapbox

您好,我的Android版MapBox SDK出现问题,我在项目中使用了Kotlin语言,并且Viewmap值始终出现问题。我是Kotlin的新手,所以也许我跳过了一些。

我制作了bottom_navigation_bar,所以我使用片段在应用程序中导航。

我的片段类是我使用的变量

package com.example.parky.parky_android
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.mapbox.mapboxsdk.constants.Style
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;

class ItemFourFragment : Fragment() {

private lateinit var mapView: MapView

fun onCreate(savedInstanceState: Bundle?, context: Context, inflater: LayoutInflater, container: ViewGroup?) {
    super.onCreate(savedInstanceState)
    // Mapbox Access token
    Mapbox.getInstance(context, getString(R.string.token_mapbox))
    val view = inflater.inflate(R.layout.activity_main, container ,false)

    mapView = view.findViewById(R.id.mapview)
    mapView.onCreate(savedInstanceState)
    mapView.getMapAsync({
        it.setStyle(Style.SATELLITE)
        // Customize map with markers, polylines, etc.
    })
}

override fun onStart() {
    super.onStart()
    mapView.onStart()
}

override fun onResume() {
    super.onResume()
    mapView.onResume()

}
override fun onPause() {
    super.onPause()
    mapView.onPause()
}
override fun onStop() {
    super.onStop()
    mapView.onStop()

}
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    mapView.onSaveInstanceState(outState)

}
override fun onLowMemory() {
    super.onLowMemory()
    mapView.onLowMemory()

}
override fun onDestroy() {
    super.onDestroy()
    mapView.onDestroy()
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_item_four, container, false)
}

companion object {
    fun newInstance(): ItemFourFragment {
        val fragment = ItemFourFragment()
        return fragment
    }
}
}

我显示它的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ItemFiveFragment">

<com.mapbox.mapboxsdk.maps.MapView
    android:id="@+id/mapview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    mapbox:mapbox_cameraTargetLat="41.885"
    mapbox:mapbox_cameraTargetLng="-87.679"
    mapbox:mapbox_styleUrl="@string/mapbox_style_satellite"
    mapbox:mapbox_cameraTilt="20"
    mapbox:mapbox_cameraZoom="12"/>
</RelativeLayout>

最后是日志

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.parky.parky_android, PID: 30820
              kotlin.UninitializedPropertyAccessException: lateinit property mapView has not been initialized
                  at com.example.parky.parky_android.ItemFourFragment.onStart(ItemFourFragment.kt:42)
                  at android.support.v4.app.Fragment.performStart(Fragment.java:2372)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1467)
                  at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
                  at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
                  at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
                  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
                  at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
                  at android.os.Handler.handleCallback(Handler.java:789)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6938)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

你知道是什么问题吗?

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

所以在这里:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_item_four, container, false)
}

您将返回一个将附加到Fragment并实际显示的视图。

这里:

fun onCreate(savedInstanceState: Bundle?, context: Context, inflater: LayoutInflater, container: ViewGroup?) {
    super.onCreate(savedInstanceState)
    // Mapbox Access token
    Mapbox.getInstance(context, getString(R.string.token_mapbox))
    val view = inflater.inflate(R.layout.activity_main, container ,false)

    mapView = view.findViewById(R.id.mapview)
    mapView.onCreate(savedInstanceState)
    mapView.getMapAsync({
        it.setStyle(Style.SATELLITE)
        // Customize map with markers, polylines, etc.
    })
}

您正在膨胀一个从未附加到任何东西的新视图。它还夸大了一个单独的布局activity_main.xml,我认为其中不包含MapView

相反,在MapView中返回膨胀视图后,您应该在onViewCreated()中解析onCreateView()

override fun onViewCreated(View view, Bundle savedState) {
    mapView = view.findViewById(R.id.mapview).apply {
        onCreate(savedState)
        getMapAsync { map -> 
            map.setStyle(Style.SATELLITE)
        }
    }
}

您也不应该为此属性使用lateinit var,因为不能保证会创建视图(例如,onCreateView()可能永远不会被调用)。这种情况的一个实例是您的Fragment在后​​台堆栈上并且对用户不可见。在Activity进行配置更改或重新创建时,后堆栈上的Fragment将通过onCreate(),但不会创建视图。在这种情况下,您会在onStart()中尝试引用尚未初始化的mapView时崩溃。

相反,将其保留为空,然后使用mapView?.doThing()执行操作。