通过单击 Android MapsFragment 中的地图隐藏 UI 元素
Hide a UI element by clicking on the map in Android MapsFragment
我正在尝试在 Android 中创建一个如下所示的 MapType 选择器:
我可以隐藏和取消隐藏小地图选择器 UI 元素。我还想在元素可见时单击地图时关闭 UI 元素,但是一旦我添加
setOnMapClickListener()
到 onCreateView
我收到以下错误:
错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.wherecownow, PID: 5856
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setOnMapClickListener(com.google.android.gms.maps.GoogleMap$OnMapClickListener)' on a null object reference
at com.example.wherecownow.ui.home.MapsFragment.onCreateView(MapsFragment.java:210)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722)
at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
at android.app.Activity.performStart(Activity.java:8024)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我了解到地图尚未创建,因此抛出 Nullpointer 错误。
我尝试将 setOnMapClickListener()
放在 onMapReady()
中,但从这里我无法引用 findViewbyID
.
非常感谢您的帮助。我在这里搜索了每一个类似的问题,但 none 已经解决了我的具体问题。
MapsFragment
public class MapsFragment extends Fragment {
private GoogleMap mMap;
private OnMapReadyCallback callback = new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng sydney = new LatLng(-34, 151);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_maps, container, false);
ConstraintLayout mConstraintLayout= (ConstraintLayout) view.findViewById(R.id.map_type_selection);
FloatingActionButton maptype_fab = (FloatingActionButton) view.findViewById(R.id.map_type_FAB);
maptype_fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mConstraintLayout.setVisibility(View.VISIBLE);
maptype_fab.setVisibility(View.INVISIBLE);
if(mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL) {
map_def_back.setVisibility(View.VISIBLE);
map_text_def.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: normal ");
} else if (mMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID){
map_sat_back.setVisibility(View.VISIBLE);
map_text_sat.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: satellite ");
} else {
map_ter_back.setVisibility(View.VISIBLE);
map_text_ter.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: terrain ");
}
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mConstraintLayout.setVisibility(View.INVISIBLE);
maptype_fab.setVisibility(View.VISIBLE);
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment =
(SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(callback);
}
}
}
你的mMap.setOnMapClickListener()
在public View onCreateView()
中被调用了,但是mMap
对象在onMapReady()
被调用后才能得到。所以你需要定义
ConstraintLayout mConstraintLayout;
FloatingActionButton maptype_fab;
作为MapsFragment
字段和移动代码:
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mConstraintLayout.setVisibility(View.INVISIBLE);
maptype_fab.setVisibility(View.VISIBLE);
}
});
至public void onMapReady()
。
我正在尝试在 Android 中创建一个如下所示的 MapType 选择器:
我可以隐藏和取消隐藏小地图选择器 UI 元素。我还想在元素可见时单击地图时关闭 UI 元素,但是一旦我添加
setOnMapClickListener()
到 onCreateView
我收到以下错误:
错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.wherecownow, PID: 5856
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setOnMapClickListener(com.google.android.gms.maps.GoogleMap$OnMapClickListener)' on a null object reference
at com.example.wherecownow.ui.home.MapsFragment.onCreateView(MapsFragment.java:210)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722)
at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2577)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
at android.app.Activity.performStart(Activity.java:8024)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我了解到地图尚未创建,因此抛出 Nullpointer 错误。
我尝试将 setOnMapClickListener()
放在 onMapReady()
中,但从这里我无法引用 findViewbyID
.
非常感谢您的帮助。我在这里搜索了每一个类似的问题,但 none 已经解决了我的具体问题。
MapsFragment
public class MapsFragment extends Fragment {
private GoogleMap mMap;
private OnMapReadyCallback callback = new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng sydney = new LatLng(-34, 151);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_maps, container, false);
ConstraintLayout mConstraintLayout= (ConstraintLayout) view.findViewById(R.id.map_type_selection);
FloatingActionButton maptype_fab = (FloatingActionButton) view.findViewById(R.id.map_type_FAB);
maptype_fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mConstraintLayout.setVisibility(View.VISIBLE);
maptype_fab.setVisibility(View.INVISIBLE);
if(mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL) {
map_def_back.setVisibility(View.VISIBLE);
map_text_def.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: normal ");
} else if (mMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID){
map_sat_back.setVisibility(View.VISIBLE);
map_text_sat.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: satellite ");
} else {
map_ter_back.setVisibility(View.VISIBLE);
map_text_ter.setTextColor(Color.BLUE);
Log.d(TAG, "maptype: terrain ");
}
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mConstraintLayout.setVisibility(View.INVISIBLE);
maptype_fab.setVisibility(View.VISIBLE);
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment =
(SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(callback);
}
}
}
你的mMap.setOnMapClickListener()
在public View onCreateView()
中被调用了,但是mMap
对象在onMapReady()
被调用后才能得到。所以你需要定义
ConstraintLayout mConstraintLayout;
FloatingActionButton maptype_fab;
作为MapsFragment
字段和移动代码:
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mConstraintLayout.setVisibility(View.INVISIBLE);
maptype_fab.setVisibility(View.VISIBLE);
}
});
至public void onMapReady()
。