Archie.bpgc
Archie.bpgc

Reputation: 24012

MapView in a Dialog

I have a DialogFragment shown as a dialog using dialogFragment.show(this);

The content view of this fragment is a ScrollView with a MapView at the bottom. onInterceptTouchEventis taken care for the ScrollView because of the presence of a MapView. And it works fine when used as a normal fragment. But as a dialog, this is what happens while scrolling.

enter image description here

enter image description here

The MapView goes out of the Dialog.

EDIT:

This didn't work:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="160dp"
    android:layout_below="@id/view_text" >

    <com.google.android.gms.maps.MapView
        android:id="@+id/view_map"
        android:layout_width="match_parent"
        android:layout_height="160dp"
        map:uiRotateGestures="true"
        map:uiScrollGestures="true"
        map:uiTiltGestures="false"
        map:uiZoomControls="false"
        map:uiZoomGestures="true" />

    <View
        android:layout_width="match_parent"
        android:layout_height="160dp" />
</RelativeLayout>

Upvotes: 2

Views: 4684

Answers (3)

For me, to make it work correctly I only need to add the style to de dialog:

<style name="Theme.CustomDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

The onCreateDialog method from the Dialog fragment:

 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = Dialog(activity,
            R.style.Theme_CustomDialog)
    val inflater = activity?.layoutInflater
    val view = inflater?.inflate(R.layout.poi_details_dialog_fragment, null)
    dialog.setContentView(view)

    //Putting the size of the window with margins
    val display = activity?.windowManager?.defaultDisplay
    val size = Point()
    display?.getSize(size)
    val width = size.x
    val height = size.y
    dialog.window.setLayout(width - resources
            .getDimensionPixelSize(R.dimen.margin_start_poi_dialog),
            height - resources
                    .getDimensionPixelSize(R.dimen.margin_top_poi_dialog))

    return dialog
}

Upvotes: 0

Chirag Jain
Chirag Jain

Reputation: 1612

Well These are the steps i used to follow when i have to put a map in dialog or a fragment (or view pager).

Prerequisite: Already have play services library, added permission like INTERNET, WRITE_EXTERNAL_STORAGE and metadata of map key and play services.

Step 1 : Create a transparent map class for using maps This class will add maps in a transparent frame layout for removing default black layer (appears in some devices).

public class TransparentMapFragment extends MapFragment {

    public TransparentMapFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup view,
            Bundle savedInstance) {
        View layout = super.onCreateView(inflater, view, savedInstance);

        FrameLayout frameLayout = new FrameLayout(getActivity());
        frameLayout.setBackgroundColor(getResources().getColor(
                android.R.color.transparent));
        ((ViewGroup) layout).addView(frameLayout, new ViewGroup.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        return layout;
    }

    public static TransparentMapFragment newInstance(String abc) {
        TransparentMapFragment tsf = new TransparentMapFragment();
        return tsf;
    }
}

Step 2 : For Dialog Fragment change style of dialog fragment

    <style name="Theme.Default.Dialog" parent="@android:style/Theme.Dialog"></style>

    <style name="Theme.CustomDialog" parent="Theme.Default.Dialog">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
    </style>

Step 3: Layout of Dialog Created a full screen dialog and added padding according to your need. Here i am using 60dip

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="60dip" >

    <ScrollView [Use your lockable scroll view]
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dip"
                android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&apos;s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum has been the industry&apos;s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
                android:textColor="#000"
                android:textSize="12sp" />


            <fragment
                android:id="@+id/map"
                android:name="com.app.widgets.TransparentMapFragment [Path of Transparent Map]"
                android:layout_width="match_parent"
                android:layout_height="100dip" />
        </LinearLayout>
    </ScrollView>


</FrameLayout>

Step 4 : Setup Dialog fragment class Normal Implementation of Map

public class MapDialogFragment extends DialogFragment {

    private View view;

    private GoogleMap mMap;
    private double lat;
    private double lon;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Dialog dialog = new Dialog(getActivity(),
                R.style.Theme_CustomDialog);
        LayoutInflater inflater = getActivity().getLayoutInflater();
        view = inflater.inflate(R.layout.dialog_map, null);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        // Creating Full Screen
        dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT);

        return dialog;
    }

    @Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);

        initializeViews();

    }

    private void initializeViews() {

        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.

        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((TransparentMapFragment) getActivity().getFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            mMap.getUiSettings().setZoomControlsEnabled(false);

            if (isGoogleMapsInstalled()) {
                if (mMap != null) {
                    setUpMap();
                }
            } else {
                Builder builder = new AlertDialog.Builder(getActivity());
                builder.setMessage("installGoogleMaps");
                builder.setCancelable(false);
                builder.setPositiveButton("install", getGoogleMapsListener());
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        }
    }

    private void setUpMap() {

        lat = 28.6100;
        lon = 77.2300;

        final LatLng position = new LatLng(lon, lat);
        mMap.clear();
        mMap.getUiSettings().setAllGesturesEnabled(false);
        mMap.addMarker(new MarkerOptions().position(position).snippet(""));
    }

    public boolean isGoogleMapsInstalled() {
        try {
            getActivity().getPackageManager().getApplicationInfo(
                    "com.google.android.apps.maps", 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    public android.content.DialogInterface.OnClickListener getGoogleMapsListener() {
        return new android.content.DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(
                        Intent.ACTION_VIEW,
                        Uri.parse("market://details?id=com.google.android.apps.maps"));
                startActivity(intent);

                // Finish the fragment so they can't circumvent the check
                if (getActivity() != null) {
                    Fragment fragment = (getActivity().getFragmentManager()
                            .findFragmentByTag(MapFragment.class.getName()));
                    FragmentTransaction ft = getActivity().getFragmentManager()
                            .beginTransaction();
                    ft.remove(fragment);
                    ft.commitAllowingStateLoss();
                }
            }

        };
    }

    @Override
    public void onDestroyView() {

        super.onDestroyView();
        if (getActivity() != null) {
            try {
                Fragment fragment = (getActivity().getFragmentManager()
                        .findFragmentById(R.id.map));
                FragmentTransaction ft = getActivity().getFragmentManager()
                        .beginTransaction();
                ft.remove(fragment);
                ft.commitAllowingStateLoss();
            } catch (Exception e) {

            }
        }

    }

}

Result :

result 1

result 2

result 3

Hope it will help thanks. :)

Upvotes: 2

Oleksii K.
Oleksii K.

Reputation: 5419

This is well-known issue. Try to wrap MapView with this structure (original post here).

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="160dp"
    >

    <com.google.android.gms.maps.MapView
        android:id="@+id/view_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        map:uiRotateGestures="true"
        map:uiScrollGestures="true"
        map:uiTiltGestures="false"
        map:uiZoomControls="false"
        map:uiZoomGestures="true"
        />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</FrameLayout>

Upvotes: 1

Related Questions