等到Fragment的`onCreateView()`方法完成后再从父Activity

时间:2017-11-27 19:56:08

标签: android google-maps user-interface android-fragments listener

我有以下显示MapView的片段。

public class MapFragment extends Fragment {

    private GoogleMap googleMap;
    private MapView mapView;
    private Location currentLocation;

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);

        mapView = (MapView) view.findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
        mapView.onResume();

        MapsInitializer.initialize(getActivity().getApplicationContext());

        // Move My Location button to bottom right
        View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
        RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        rlp.setMargins(0, 0, 30, 30);

        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap gMap) {
                googleMap = gMap;
                googleMap.setMapStyle(new MapStyleOptions(getResources().getString(R.string.map_style)));

                if (!checkPermission())
                    askPermission();        // NOT WORKING PROPERLY
                if (checkPermission()) {
                    googleMap.setMyLocationEnabled(true);
                    zoomToCurrentLocation();
                }
                //else handle no location permissions

            }
        });

        return view;
    }

    private void zoomToCurrentLocation() {
        LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        if (checkPermission())
            currentLocation = locationManager.getLastKnownLocation(bestProvider);
        LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
        googleMap.animateCamera(zoomTo(15));
        googleMap.moveCamera(newLatLngZoom(latLng, 15));

        LocationListener locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if(location != null) {
                    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                    googleMap.animateCamera(zoomTo(15));
                    googleMap.moveCamera(newLatLngZoom(latLng, 15));
                }
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) { }

            @Override
            public void onProviderEnabled(String s) { }

            @Override
            public void onProviderDisabled(String s) { }
        };

        locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);
    }

    public void disallowInteraction() {
        googleMap.getUiSettings().setAllGesturesEnabled(false);
        googleMap.getUiSettings().setMyLocationButtonEnabled(false);
    }

    public void allowInteraction() {
        googleMap.getUiSettings().setAllGesturesEnabled(true);
        googleMap.getUiSettings().setMyLocationButtonEnabled(true);
    }

    private boolean checkPermission() {
        return (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED );
    }

    private void askPermission() {
        ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, 1);
    }
}

它将被添加到多个活动中,并且根据活动,我想在MapView中将不同的UI元素设置为活动或不活动 - 这些元素在allowInteraction()和{{1}中打开或关闭}}

目前,当我尝试从父Activity的disallowInteraction()方法调用这些方法时:

onCreate()
该应用程序崩溃了。我认为这是因为Fragment的mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.workoutActivityMap); mapFragment.allowInteraction(); 实例变量尚未进入googleMap。如何从父Activity调用这些方法,但只有Fragment允许调用它们?

修改

MapFragment.java

OnMapReadyCallback()

fragment_map.xml

public class MapFragment extends Fragment {

    private GoogleMap googleMap;
    private MapView mapView;
    private Location currentLocation;
    FragmentListener fragmentListener;

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);

        mapView = (MapView) view.findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
        mapView.onResume();

        MapsInitializer.initialize(getActivity().getApplicationContext());

        // Move My Location button to bottom right
        View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
        RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        rlp.setMargins(0, 0, 30, 30);

        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap gMap) {
                googleMap = gMap;
                googleMap.setMapStyle(new MapStyleOptions(getResources().getString(R.string.map_style)));

                if (!checkPermission())
                    askPermission();        // NOT WORKING PROPERLY
                if (checkPermission()) {
                    googleMap.setMyLocationEnabled(true);
                    zoomToCurrentLocation();
                }
                //else handle no location permissions
                fragmentListener.onMapFragmentReady();
            }
        });

        return view;
    }

    private void zoomToCurrentLocation() {
        LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        if (checkPermission())
            currentLocation = locationManager.getLastKnownLocation(bestProvider);
        LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
        googleMap.animateCamera(zoomTo(15));
        googleMap.moveCamera(newLatLngZoom(latLng, 15));

        LocationListener locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if(location != null) {
                    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                    googleMap.animateCamera(zoomTo(15));
                    googleMap.moveCamera(newLatLngZoom(latLng, 15));
                }
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) { }

            @Override
            public void onProviderEnabled(String s) { }

            @Override
            public void onProviderDisabled(String s) { }
        };

        locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);
    }

    public void disallowInteraction() {
        googleMap.getUiSettings().setAllGesturesEnabled(false);
        googleMap.getUiSettings().setMyLocationButtonEnabled(false);
    }

    public void allowInteraction() {
        googleMap.getUiSettings().setAllGesturesEnabled(true);
        googleMap.getUiSettings().setMyLocationButtonEnabled(true);
    }

    private boolean checkPermission() {
        return (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED );
    }

    private void askPermission() {
        ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, 1);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof FragmentListener) {
            fragmentListener = (FragmentListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement FragmentListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        fragmentListener = null;
    }

    public interface FragmentListener {
        void onMapFragmentReady();
    }
}

WorkoutActivity.java

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.maps.MapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"/>

WorkoutTabFragment.java

public class WorkoutActivity extends AppCompatActivity implements MapFragment.FragmentListener {

    MapFragment mapFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_workout);
        mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.workoutActivityMap);

        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        this.getSupportActionBar().hide();
    }

    @Override
    public void onMapFragmentReady() {
        mapFragment.allowInteraction();
    }
}

最后两个类都包含

public class WorkoutTabFragment extends Fragment implements MapFragment.FragmentListener {

    MapFragment mapFragment;

    public static WorkoutTabFragment newInstance() {
        return new WorkoutTabFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_workout_tab, container, false);
        mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.workoutTabFragmentMap);

        FloatingActionButton myFab = (FloatingActionButton)  view.findViewById(R.id.fab);
        myFab.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(WorkoutTabFragment.this.getContext(), WorkoutActivity.class);
                startActivity(intent);
            }
        });

        return view;
    }

    @Override
    public void onMapFragmentReady() {
        mapFragment.disallowInteraction();
    }
}

在他们的XML中

1 个答案:

答案 0 :(得分:0)

您需要使用接口/回调来了解片段何时完成加载地图,我使用接口修复了代码

这是你的片段:

    public class MapFragment extends Fragment {

        private GoogleMap googleMap;
        private MapView mapView;
        private Location currentLocation;
        FragmentListener mListener;

        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_map, container, false);

            mapView = (MapView) view.findViewById(R.id.map);
            mapView.onCreate(savedInstanceState);
            mapView.onResume();

            MapsInitializer.initialize(getActivity().getApplicationContext());

            // Move My Location button to bottom right
            View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
            RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
            rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
            rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
            rlp.setMargins(0, 0, 30, 30);

            mapView.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap gMap) {
                    googleMap = gMap;
                    googleMap.setMapStyle(new MapStyleOptions(getResources().getString(R.string.map_style)));

                    if (!checkPermission())
                        askPermission();        // NOT WORKING PROPERLY
                    if (checkPermission()) {
                        googleMap.setMyLocationEnabled(true);
                        zoomToCurrentLocation();
                    }
                    //else handle no location permissions
                    mListener.onMapFragmentReady();
                }
            });

            return view;
        }

        private void zoomToCurrentLocation() {
            LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            String bestProvider = locationManager.getBestProvider(criteria, true);
            if (checkPermission())
                currentLocation = locationManager.getLastKnownLocation(bestProvider);
            LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
            googleMap.animateCamera(zoomTo(15));
            googleMap.moveCamera(newLatLngZoom(latLng, 15));

            LocationListener locationListener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    if(location != null) {
                        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                        googleMap.animateCamera(zoomTo(15));
                        googleMap.moveCamera(newLatLngZoom(latLng, 15));
                    }
                }

                @Override
                public void onStatusChanged(String s, int i, Bundle bundle) { }

                @Override
                public void onProviderEnabled(String s) { }

                @Override
                public void onProviderDisabled(String s) { }
            };

            locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);
        }

        public void disallowInteraction() {
            googleMap.getUiSettings().setAllGesturesEnabled(false);
            googleMap.getUiSettings().setMyLocationButtonEnabled(false);
        }

        public void allowInteraction() {
            googleMap.getUiSettings().setAllGesturesEnabled(true);
            googleMap.getUiSettings().setMyLocationButtonEnabled(true);
        }

        private boolean checkPermission() {
            return (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED );
        }

        private void askPermission() {
            ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, 1);
        }

           @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            if (context instanceof FragmentListener) {
                mListener = (FragmentListener) context;
            } else {
                throw new RuntimeException(context.toString()
                        + " must implement FragmentListener");
            }
        }

        @Override
        public void onDetach() {
            super.onDetach();
            mListener = null;
        }

        public interface FragmentListener {
            void onMapFragmentReady();
        }
    }

这是你的活动

    public class YourActivity extends Activity implements FragmentListener {

        @Override
        public void onMapFragmentReady(){
            mapFragment.allowInteraction();
        }
    }