Search code examples
androidgoogle-mapsgoogle-maps-android-api-3

SupportMapFragment nested in Fragment makes map not reacting to gestures


I have problem with Google Maps V3. Basically I have application with HomeActivity (AppCompatActivity). In this activity I have HomeFragment (inherits from Fragment) and now what I want is to have SupportMapFragment from Google Maps library, so inside HomeFragment layout I put

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

In HomeFragment onCreateView callback I have

mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment?.getMapAsync(this)

Map is showing, but the problem is I can't do anything - I mean I can't scroll or zoom this map, it is not responding.

I tried to put MapView instead of whole fragment and map was reacting to gestures. But this solution isn't perfect - for example isMyLocationEnabled doesn't show current location icon and click on button in right upper corner is not moving camera to location (yet callback is called).

Any idea how I can solve this one?

EDIT: Layout code

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

    <variable
        name="homeVM"
        type="viewmodel.home.map.HomeViewModel" />

    <variable
        name="detailVM"
        type="viewmodel.home.map.SheetDetailViewModel" />

    <variable
        name="shareVM"
        type="viewmodel.home.map.HomeSheetShareViewModel" />

</data>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">


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

    <FrameLayout
        android:id="@+id/sidebarBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="24dp"
        android:foreground="?android:attr/selectableItemBackground"
        android:onClick="@{(v) -> homeVM.openSidebar()}"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="@drawable/white_bg_rounded"
            android:padding="10dp"
            android:tint="@color/warm_grey"
            android:src="@drawable/ic_menu_warm_gray_24dp" />
    </FrameLayout>


    <LinearLayout
        android:id="@+id/mapOptionsMenu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="72dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:animateLayoutChanges="true"
        android:background="@drawable/white_bg_rounded"
        android:divider="@drawable/line_background_margin_8"
        android:orientation="vertical"
        android:showDividers="middle"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/mapTypeBtn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?android:attr/selectableItemBackground"
            android:onClick="@{(v) -> homeVM.mapType()}"
            android:padding="10dp"
            android:src="@drawable/ic_layers_warm_gray_24dp"
            app:tint="@color/warm_grey" />

        <ImageView
            android:id="@+id/arBtn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?android:attr/selectableItemBackground"
            android:onClick="@{(v) -> homeVM.onArClick()}"
            android:padding="10dp"
            android:src="@drawable/ic_ar_warm_grey_24dp"
            app:tint="@color/warm_grey" />

        <ImageView
            android:id="@+id/myTrackerLocationBtn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?android:attr/selectableItemBackground"
            android:onClick="@{(v) -> homeVM.myTrackerLocation()}"
            android:padding="10dp"
            android:scaleType="fitXY"
            android:src="@drawable/ic_navigation_on_warm_gray_24dp"
            app:tint="@color/warm_grey" />

        <ImageView
            android:id="@+id/myLocationBtn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?android:attr/selectableItemBackground"
            android:onClick="@{(v) -> homeVM.myLocation()}"
            android:padding="8dp"
            android:src="@drawable/ic_navigation_on_warm_gray_24dp"
            app:tint="@color/warm_grey" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/trackerOptionsMenu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:animateLayoutChanges="true"
        android:background="@drawable/white_bg_rounded"
        android:divider="@drawable/line_background_margin_8"
        android:orientation="vertical"
        android:showDividers="middle"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mapOptionsMenu">

        <view.AnimatedRefreshImageView
            android:id="@+id/refreshBtn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:onClick="@{(v) -> homeVM.refresh(shareVM.items)}"
            app:layout_constraintBottom_toTopOf="@+id/myLocationBtn"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/myTrackerLocationBtn"/>

        <ImageView
            android:id="@+id/supertracking_btn"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?android:attr/selectableItemBackground"
            android:onClick="@{(v) -> homeVM.superTracking(shareVM.selected.id)}"
            android:padding="10dp"
            android:src="@drawable/drawable_superlive" />

    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/trackersSheet"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <activity.home.home.fragments.sheet.TrackersSheet
            android:id="@+id/list_sheet"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="bottom"
            android:layout_marginTop="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            bind:items="@{shareVM.items}"
            bind:visible="@{shareVM.selected == null}"/>

        <activity.home.home.fragments.sheet.DetailSheet
            android:id="@+id/detail_sheet"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="bottom"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            bind:isAutoSelect="@{shareVM.isAutoSelect}"
            bind:setAutoSelectTracker="@{shareVM.items[0]}"
            bind:tracker="@{shareVM.selected}"
            bind:viewModel="@{detailVM}"
            bind:visible="@{shareVM.selected != null || shareVM.isAutoSelect}">

        </activity.home.home.fragments.sheet.DetailSheet>
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.github.stkent.amplify.prompt.DefaultLayoutPromptView
        android:id="@+id/prompt_view"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:prompt_view_background_color="@color/blood_orange"
        app:prompt_view_button_corner_radius="15dp"
        app:prompt_view_critical_feedback_question_negative_button_label="@string/prompt_view_feedback_negative"
        app:prompt_view_critical_feedback_question_positive_button_label="@string/prompt_view_feedback_positive"
        app:prompt_view_critical_feedback_question_title="@string/prompt_view_feedback_question_title"
        app:prompt_view_positive_feedback_question_negative_button_label="@string/prompt_view_rate_negative"
        app:prompt_view_positive_feedback_question_positive_button_label="@string/prompt_view_rate_positive"
        app:prompt_view_positive_feedback_question_title="@string/prompt_view_rate_title"
        app:prompt_view_thanks_display_time_ms="2000"
        app:prompt_view_user_opinion_question_negative_button_label="@string/general_no"
        app:prompt_view_user_opinion_question_positive_button_label="@string/general_yes"
        app:prompt_view_user_opinion_question_title="@string/prompt_view_question_title" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/productRating"
        android:layout_width="match_parent"
        android:layout_height="170dp"
        android:background="@color/blood_orange"
        android:visibility="@{homeVM.productRatingVisibility}"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:visibility="visible">

        <TextView
            android:id="@+id/productRatingTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="@string/product_rating_popup_title"
            android:textColor="@color/white"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/productRatingMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="12dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="@string/product_rating_popup_message"
            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/productRatingTitle" />

        <Button
            android:id="@+id/productRatingNoBtn"
            style="@style/Button.Rounded.Orange"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:text="@string/product_rating_nothanks_btn"
            android:onClick="@{(v) -> homeVM.postponeRating()}"
            app:layout_constraintEnd_toStartOf="@+id/guideline9"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/productRatingMsg" />

        <Button
            android:id="@+id/productRatingYesBtn"
            style="@style/Button.Rounded.White"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="@string/product_rating_answer_btn"
            android:onClick="@{(v) -> homeVM.answerRating()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline9"
            app:layout_constraintTop_toBottomOf="@+id/productRatingMsg" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

Solution

  • Ok, I figured it out. Finally. It wasn't Google Maps SDK issue, but something in code. We got this project in late state of development from other company and I wasn't aware of this.

    It was all about this piece of code:

    if (view is ViewGroup && !isHomeFragment()) {
            view.hideSoftKeyboardOnTouchOutside()
    }
    
    fun ViewGroup.hideSoftKeyboardOnTouchOutside() {
    this.childrenRecursiveSequence()
            .filter { it !is EditText }
            .forEach {
                it.setOnTouchListener { view, _ ->
                    view.hideSoftKeyboard()
                    false
                }
            }
    }
    

    It was executed in base fragment onViewCreated callback on inheriting fragment view. Somehow it didn't affect MapBox map reaction to gestures unlike Google map, which was quite useless in that case.