Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NavigationView compatibility with Fragment #623

Closed
harisqurashi opened this issue Jan 2, 2018 · 13 comments
Closed

NavigationView compatibility with Fragment #623

harisqurashi opened this issue Jan 2, 2018 · 13 comments

Comments

@harisqurashi
Copy link

harisqurashi commented Jan 2, 2018

NavigationView needs onCreate, onBackPressedand and onRestoreInstanceState which doesn't allowed inside fragment implementation. As far as i understand given example is for activity only but for fragment we are unable to use NavigationView life cycle methods.

As we can not call navigationView.onCreate inside Fragment's onCreate can we use navigationView.onCreate(null) inside onCreateView or onViewCreated but what about onBackPressedand onRestoreInstanceState in fragment.

@danesfeder
Copy link
Contributor

Hey @m-harisqurashi thanks for bringing this to us. You're right, we need to add some documentation for how to implement the NavigationView in a fragment.

It's not immediately obvious, but this is how you can call onCreate and onRestoreInstanceState:

  @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View  v = super.onCreateView(inflater, container, savedInstanceState);

       navigationView = v.findViewById(R.id.navigationView);
       navigationView.onCreate(savedInstanceState);
       navigationView.getNavigationAsync(this);
       return v;
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        navigationView.onLowMemory();
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        navigationView.onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if(savedInstanceState!=null)
            navigationView.onRestoreInstanceState(savedInstanceState);
    }

Back pressed is tricky as there isn't a way to listen to this in a Fragment directly, but not adding this won't crash your app. We will look into a solution to fix this on our end.

@langsmith
Copy link
Contributor

@danesfeder , I also think that onDestroyView() might need to be added/addressed as well

It's missing from these NavigationView overrides:

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
mapView.onStart();
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
mapView.onResume();
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
mapView.onPause();
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
mapView.onStop();
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
mapView.onDestroy();
}

Related mapbox/mapbox-gl-native#10809 (comment) too

@danesfeder
Copy link
Contributor

danesfeder commented Jan 5, 2018

The destroy issue is being worked --> #632

@harisqurashi
Copy link
Author

When click on cancelBtn it doesn't close NavigationView as well Notification. What we are doing is to hide the NavigationView but what about notification, how can we cancel that notification in statusbar.

@danesfeder
Copy link
Contributor

@m-harisqurashi can you share your Fragment code? The notification should be destroyed when the Service that runs the navigation processing is destroyed and this happens when you click the cancelBtn

@harisqurashi
Copy link
Author

harisqurashi commented Jan 9, 2018

Service is not destroying if i use builtin navigation notification or custom. In both cases i see a non cancel-able notification in my statubar (it works only for builtin notification when i close notification by clicking on cancel button in notification).
For both cases i get onCancelNavigation and onNavigationFinished events but NavigationView and Service/Notification keeps on screen.

I've created a MapNavigationPresenter. This model can use in both Activity and Fragment. Below is my code for MapboxNavigation.

public class MapboxNavigationPresenterImpl implements MapNavigationPresenter, OnNavigationReadyCallback, NavigationListener {

    private String TAG = "MapboxNavigationPresenterImpl";
    private NavigationView navigationView = null;
    private WeakReference<OnMapNavigationCallback> navigationCallback = null;

    public MapboxNavigationPresenterImpl(OnMapNavigationCallback callback) {
        if (callback == null)
            throw new NullPointerException("OnMapNavigationCallback can not be null");
        navigationCallback = new WeakReference<>(callback);
    }

    // region MAP_NAVIGATION_PRESENTER
    @Override
    public void initializeMapNavigation(View view, Bundle savedInstanceState) {
        if (view == null) {
            throw new NullPointerException("View  can not be null");
        }

        navigationView = view.findViewById(R.id.view_group_mapbox);
        navigationView.onCreate(savedInstanceState);
    }

    @Override
    public void startMapNavigation() {
        ZemLogs.info(TAG, "startMapNavigation");
        OnMapNavigationCallback callback = getMapNavigationCallback();
        TripSolo trip = new RushSearch().whereEqual("mRideID", callback.getRideId()).findSingle(TripSolo.class);
        if (trip == null)
            return;

        callback.onBeforeNavigation();
        navigationView.getNavigationAsync(this);
    }

    @Override
    public void onSaveInstanceState(Bundle onSaveInstanceState) {
        navigationView.onSaveInstanceState(onSaveInstanceState);
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        if (savedInstanceState != null)
            navigationView.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    public void onLowMemory() {
        navigationView.onLowMemory();
    }

    @Override
    public void onBackPressed() {
    }

    @Override
    public void onDestroy() {
        TAG = null;
        navigationView.onDestroy();
        navigationView = null;

        navigationCallback.clear();
        navigationCallback = null;
    }
    // endregion

    // region MAPBOX_NAVIGATION
    @Override
    public void onNavigationReady() {
        ZemLogs.info(TAG, "onNavigationReady");

        OnMapNavigationCallback callback = getMapNavigationCallback();
        LatLng endLocation = callback.getNavigationEndLocation();
        LatLng startLocation = callback.getNavigationStartLocation();

        Point origin = Point.fromLngLat(startLocation.longitude, startLocation.latitude);
        Point destination = Point.fromLngLat(endLocation.longitude, endLocation.latitude);

        MapboxNavigationOptions navigationOptions = MapboxNavigationOptions.builder()
                .unitType(NavigationUnitType.TYPE_IMPERIAL)
                //.navigationNotification(callback.getCustomNavigationNotification())
                .build();

        NavigationViewOptions options = NavigationViewOptions.builder()
                .origin(origin)
                .destination(destination)
                .awsPoolId(null)
                .shouldSimulateRoute(true)
                .navigationOptions(navigationOptions)
                .navigationListener(this)
                .build();

        navigationView.startNavigation(options);
    }

    @Override
    public void onCancelNavigation() {
        ZemLogs.info(TAG, "onCancelNavigation");
        getMapNavigationCallback().onCancelNavigation();
    }

    @Override
    public void onNavigationFinished() {
        ZemLogs.info(TAG, "onNavigationFinished");
        getMapNavigationCallback().onCompleteNavigation();
    }

    @Override
    public void onNavigationRunning() {
        ZemLogs.info(TAG, "onNavigationRunning");
        // do nothing
    }
    // endregion

    private OnMapNavigationCallback getMapNavigationCallback() {
        return navigationCallback.get();
    }
}

@harisqurashi
Copy link
Author

According to NavigationService

This class is first created and started when {@link MapboxNavigation#startNavigation(DirectionsRoute)} get's called and runs in the background until either the navigation sessions ends implicitly or the hosting activity gets destroyed.

But incase of fragment we may or may not destroy Fragment and service keeps running in background, there should be a way to call MapboxNavigation.onDestroy from NavigationView or through any wrapper class

@danesfeder
Copy link
Contributor

@m-harisqurashi Yeah you're right, good catch here. Found the issue and should be addressed in #643

@hakobast
Copy link

hakobast commented Mar 5, 2018

Hi guys calling navigationView.onDestroy() in Fragment's onDestroyView throwing fatal error.

@danesfeder
Copy link
Contributor

@hakobast do you mind opening a new issue to track this? Can you please include the version of the SDK you're using and a stack trace for the error? Thanks!

@hakobast
Copy link

hakobast commented Mar 6, 2018

@danesfeder yes i can open new issue. SDK version is 'com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.10.0' here is the stack trace.

A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7 in tid 10070 (pachage-name), pid 10070 (package-name)

maybe this is related to issue
03-06 12:13:50.786 10397-10397/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 03-06 12:13:50.787 10397-10397/? A/DEBUG: Build fingerprint: 'google/bullhead/bullhead:8.1.0/OPM3.171019.014/4503998:user/release-keys' 03-06 12:13:50.787 10397-10397/? A/DEBUG: Revision: 'rev_1.0' 03-06 12:13:50.787 10397-10397/? A/DEBUG: ABI: 'arm64' 03-06 12:13:50.787 10397-10397/? A/DEBUG: pid: 10070, tid: 10070, name: com.gofolo >>> com.gofolo <<< 03-06 12:13:50.787 10397-10397/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7 03-06 12:13:50.787 10397-10397/? A/DEBUG: Cause: null pointer dereference 03-06 12:13:50.787 10397-10397/? A/DEBUG: x0 00000073584b5fc0 x1 0000007ff64a6c60 x2 0000000000000000 x3 000000736e4ee17a 03-06 12:13:50.787 10397-10397/? A/DEBUG: x4 0000007ff64a6c40 x5 0000007ff64a6cb8 x6 404643b651abef87 x7 40441a41866f4b0c 03-06 12:13:50.787 10397-10397/? A/DEBUG: x8 ffffffffffffffff x9 70226fcda66f4786 x10 0000000000430000 x11 000000736e5ac7a8 03-06 12:13:50.787 10397-10397/? A/DEBUG: x12 0000000000000002 x13 0000000000000001 x14 0000000000000078 x15 0000000000000000 03-06 12:13:50.787 10397-10397/? A/DEBUG: x16 000000736e5a9550 x17 00000073f12ab2f0 x18 0000000000000008 x19 00000073584b5fc0 03-06 12:13:50.787 10397-10397/? A/DEBUG: x20 00000073f321aa40 x21 0000007ff64a6e38 x22 000000001b648d68 x23 0000000014641c40 03-06 12:13:50.787 10397-10397/? A/DEBUG: x24 000000001464c7b8 x25 0000000000000000 x26 000000001b540930 x27 0000000000000000 03-06 12:13:50.787 10397-10397/? A/DEBUG: x28 0000007ff64a6f30 x29 0000007ff64a6e80 x30 0000007356665204 03-06 12:13:50.787 10397-10397/? A/DEBUG: sp 0000007ff64a6dc0 pc 000000735680e8f0 pstate 0000000060000000 03-06 12:13:50.817 10397-10397/? A/DEBUG: backtrace: 03-06 12:13:50.817 10397-10397/? A/DEBUG: #00 pc 00000000002e18f0 /data/app/com.gofolo-iyE8Ep75u25mezgzKT9LGw==/lib/arm64/libmapbox-gl.so 03-06 12:13:50.817 10397-10397/? A/DEBUG: #01 pc 0000000000138200 /data/app/com.gofolo-iyE8Ep75u25mezgzKT9LGw==/lib/arm64/libmapbox-gl.so 03-06 12:13:50.817 10397-10397/? A/DEBUG: #02 pc 000000000013ae14 /data/app/com.gofolo-iyE8Ep75u25mezgzKT9LGw==/lib/arm64/libmapbox-gl.so 03-06 12:13:50.817 10397-10397/? A/DEBUG: #03 pc 000000000013ae68 /data/app/com.gofolo-iyE8Ep75u25mezgzKT9LGw==/lib/arm64/libmapbox-gl.so 03-06 12:13:50.817 10397-10397/? A/DEBUG: #04 pc 0000000000553bf0 /system/lib64/libart.so (art_quick_generic_jni_trampoline+144) 03-06 12:13:50.817 10397-10397/? A/DEBUG: #05 pc 00000000000b6c4c /dev/ashmem/dalvik-jit-code-cache (deleted)

@LelicKAS
Copy link

I have the same problem .... Are there any comments on to solve it? ....

@hussi1
Copy link

hussi1 commented Sep 12, 2018

Is onDestroy added for fragment ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants