通过单击 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()