谷歌地图片段返回空对象



我想有一个与 MainActivity 不同的类来初始化 map,并有静态方法来初始化,这样它在整个项目中都保持不变,任何类都可以使用这个从类返回的 googlemap 对象,我写了一个单独的类

public class MapFragment extends AppCompatActivity{
public static SupportMapFragment mapFrag;
public static SupportMapFragment GetMapObj() {
   mapFrag = (SupportMapFragment) new MainActivity().
   getSupportFragmentManager().findFragmentById(R.id.frag_map);
}

在主活动中像这样使用它

SupportMapFragment mapFragment = MapFragment.GetMapObj();
        mapFragment.getMapAsync(this);

我有 2 个 xml 1 用于上面的类和 1 个用于主活动我不知道我应该把我的

 <fragment
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/frag_map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    tools:context="com.example.sarahn.clientapimap.MainActivity"
    />

说了这么多,我的应用程序在空指针异常上崩溃,试图在空对象引用上调用getAsncMap。

}

由于mapFragment未正确初始化,因此您正在NullPointerException

改为在MainActivity中初始化SupportMapFragment

main_activity_xml

 <fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

现在在您的MainActivity

 public class MainActivity extends FragmentActivity implements OnMapReadyCallback{

  SupportMapFragment smp;
  GoogleMap mMap;
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity_xml);
        smp = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        smp.getMapAsync(this);
        }
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;
        //map initialized
    }
}

如果您希望您的活动在用户在地图中执行某些操作时执行某些操作,请尝试此操作。

public class YourFragment extends Fragment implements OnMapReadyCallback,
    GoogleMap.OnMapClickListener,
    GoogleMap.OnMarkerClickListener{
    private MapFragment mapFragment;
    private GoogleMap mMap;
    private OnMapListener onMapListener;
    public static YourFragment newInstance(){
        return new YourFragment();
    }
    @Override public void onAttach(Context context) {
        super.onAttach(context);
        try {
            this.onMapListener = (OnMapListener)context;
        }
        catch (final ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement OnMapListener");
        }
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.your_layout, container, false);
        mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id. frag_map); 
        mapFragment.getMapAsync(this); //Its async, It could last a little bit and 
        //that is the reason why you are getting NULL,
        // to work Asynchronously you should implement the Callback 'OnMapReadyCallback'.
        return rootView;
    }
    @Override public void onMapReady(GoogleMap googleMap) { 
        mMap = googleMap; 
        mMap.setOnMapClickListener(this);
        mMap.setOnMarkerClickListener(this);
    }
    @Override public void onMapClick(LatLng latLng) {
        onMapListener.onMapClick(latLng);
    }
    @Override public boolean onMarkerClick(Marker marker) {
        onMapListener.onMarkerClick(marker);
    }
    public interface OnMapListener{
        void onMapClick(LatLng latLng);
        void onMarkerClick(Marker marker);
    }
}

public class YourActivity extends AppCompatActivity implements OnMapListener {
    @Override protected void onCreate(Bundle savedInstanceState) {
        ...
        YourFragment newFragment = YourFragment.newInstance();
        ...
    }
    public void onMapClick(LatLng latLng){
    //do something on your activity
    }
    public void onMarkerClick(Marker marker){
    //do something on your activity
    }          
}

您可以在片段自己的onCreate方法中扩展SupportMapFragment和初始化映射。这样可以避免将活动与逻辑上属于片段的代码混杂在一起。

public class MyMapFragment extends SupportMapFragment {
    @Override
    public void onCreate(final Bundle bundle) {
        super.onCreate(bundle);
        getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(final GoogleMap map) {
                // configure the map here
            }
        });
    }
}

然后将其放在您的活动 XML 中,就像您对待普通SupportMapFragment一样。

<fragment
    android:id="@+id/map"
    android:name="com.myapp.MyMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

如果您仍需要从活动中访问片段,请调用 getSupportFragmentManager().findFragmentById(R.id.map) 。但由于片段配置了映射,因此活动可能不再需要访问它。使用片段的活动通常只不过是调用setContentView onCreate

问题是您正在尝试创建一个新的上下文,而不是让操作系统执行此操作。您必须在现有上下文中使用startActivity才能创建新活动。

至于你想如何获取你的地图对象,这里有一个例子:

public class MapFragment extends AppCompatActivity{
    public static SupportMapFragment mapFrag;
    public static SupportMapFragment GetMapObj(FragmentActivity activity) {
       mapFrag = (SupportMapFragment) activity.
         getSupportFragmentManager().findFragmentById(R.id.frag_map);
    }
}

在您的活动中,只需调用以下内容:

SupportMapFragment mapFragment = MapFragment.GetMapObj(this);
        mapFragment.getMapAsync(this);

最新更新