MapFragment dans ScrollView

j'en ai un de la nouvelle MapFragment dans un ScrollView . En fait, c'est un SupportMapFragment , mais de toute façon. Cela fonctionne, mais il y a deux problèmes:

  1. lorsqu'il est laminé, il laisse un masque noir derrière lui. Le noir couvre exactement la zone où se trouvait la carte, à l'exception d'un trou où se trouvaient les boutons +/- zoom. Voir la capture d'écran ci-dessous. C'est sur Android 4.0.

  2. Le point de vue n'utilise pas requestDisallowInterceptTouchEvent() lorsque l'utilisateur interagit avec la carte pour empêcher les touches d'interception ScrollView , donc si vous essayez de jouer à la verticale dans la carte, il effile juste le contenant ScrollView . Je pourrais théoriquement dériver une classe de vue MapView et ajouter cette fonctionnalité, mais comment puis-je obtenir MapFragment pour utiliser mon MapView personnalisé au lieu de celui standard?

Partial screenshot of scrolling issue

53
demandé sur Ralf 2012-12-06 19:00:53

8 réponses

appliquer une image transparente sur le fragment mapview semble résoudre le problème. Ce n'est pas la plus jolie, mais il semble fonctionner. Voici un extrait de XML qui montre ceci:

<RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="300dp" >

        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.MapFragment"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

        <ImageView
            android:id="@+id/imageView123"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/temp_transparent" />         
</RelativeLayout>
52
répondu walnut_head 2012-12-18 19:03:11

pour moi ajouter un ImageView transparent n'a pas aidé à enlever complètement le masque noir. Les parties supérieure et inférieure de la carte montraient toujours le masque noir en faisant défiler.

donc la solution pour elle, j'ai trouvé dans cette réponse avec un petit changement. J'ai ajouté,

android:layout_marginTop="-100dp"
android:layout_marginBottom="-100dp"

à mon fragment de carte puisqu'il s'agit d'un scrollview vertical. Ainsi, ma mise en page ressemblait maintenant à ceci:

<RelativeLayout
    android:id="@+id/map_layout"
    android:layout_width="match_parent"
    android:layout_height="300dp">

    <fragment
        android:id="@+id/mapview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="-100dp"
        android:layout_marginBottom="-100dp"
        android:name="com.google.android.gms.maps.MapFragment"/>

    <ImageView
        android:id="@+id/transparent_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@color/transparent" />

</RelativeLayout>   

pour résoudre le second une partie de la question j'ai mis requestDisallowInterceptTouchEvent(true) pour mon ScrollView principal. Lorsque l'Utilisateur a touché l'image transparente et déplacé j'ai désactivé le toucher sur l'image transparente pour MotionEvent.ACTION_DOWN et MotionEvent.ACTION_MOVE afin que le fragment de carte puisse prendre des événements de contact.

ScrollView mainScrollView = (ScrollView) findViewById(R.id.main_scrollview);
ImageView transparentImageView = (ImageView) findViewById(R.id.transparent_image);

transparentImageView.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        switch (action) {
           case MotionEvent.ACTION_DOWN:
                // Disallow ScrollView to intercept touch events.
                mainScrollView.requestDisallowInterceptTouchEvent(true);
                // Disable touch on transparent view
                return false;

           case MotionEvent.ACTION_UP:
                // Allow ScrollView to intercept touch events.
                mainScrollView.requestDisallowInterceptTouchEvent(false);
                return true;

           case MotionEvent.ACTION_MOVE:
                mainScrollView.requestDisallowInterceptTouchEvent(true);
                return false;

           default: 
                return true;
        }   
    }
});

ça a marché pour moi. Espérons qu'il vous aide..

35
répondu Laksh 2017-05-23 12:26:15

cela a probablement ses racines dans le même endroit à cause du problème dans cette question . La solution est d'utiliser un cadre transparent, qui est un peu plus léger qu'une image transparente.

8
répondu iagreen 2017-05-23 12:18:10

Fait après beaucoup de R&D:

fragment_one.xml devrait ressembler à:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollViewParent"
    android:orientation="vertical" >

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

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="400dip" >

            <com.google.android.gms.maps.MapView
                android:id="@+id/mapView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <View
                android:id="@+id/customView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@android:color/transparent" />
        </RelativeLayout>

        <!-- Your other elements are here -->

    </LinearLayout>

</ScrollView>

votre classe Java de FragmentOne.java ressemble à:

private GoogleMap mMap;
private MapView mapView;
private UiSettings mUiSettings;
private View customView

onreeview

mapView = (MapView) rootView.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);

if (mapView != null) {
   mMap = mapView.getMap();
   mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
   mUiSettings = mMap.getUiSettings();
   mMap.setMyLocationEnabled(true);
   mUiSettings.setCompassEnabled(true); 
   mUiSettings.setMyLocationButtonEnabled(false);
}


scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);

customView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        // Disallow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        // Disable touch on transparent view
                        return false;

                    case MotionEvent.ACTION_UP:
                        // Allow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(false);
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        return false;

                    default:
                        return true;
                }
            }
        });
3
répondu Hiren Patel 2015-04-29 10:45:21

j'ai utilisé ces structures et j'ai surmonté le problème.

j'ai utilisé une vue de conteneur pour fragment de cartes.

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <TextView
            android:text="Another elements in scroll view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


        <com.erolsoftware.views.MyMapFragmentContainer
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="250dp">

            <fragment
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/eventMap"
                tools:context="com.erolsoftware.eventapp.EventDetails"
                android:name="com.google.android.gms.maps.SupportMapFragment"/>

        </com.erolsoftware.views.MyMapFragmentContainer>

        <TextView
            android:text="Another elements in scroll view2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />



    </LinearLayout>




</ScrollView>

la classe de réservoir:

public class MyMapFragmentContainer extends LinearLayout {


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
        {
            ViewParent p = getParent();
            if (p != null)
                p.requestDisallowInterceptTouchEvent(true);
        }

        return false;
    }

    public MyMapFragmentContainer(Context context) {
        super(context);
    }

    public MyMapFragmentContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyMapFragmentContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

}
2
répondu Erkan Erol 2014-12-08 14:34:46

pas besoin de lutter avec customScrollViews et les fichiers de mise en page transparents. simplement utiliser la version plus légère de google map et votre problème sera résolu.

  map:liteMode="true"

ajouter la propriété ci-dessus dans fragment de carte dans votre fichier de mise en page. et le problème sera résolu.

1
répondu Hammad Tariq 2017-12-11 11:23:29

pour la deuxième partie de la question - vous pouvez dériver une classe de fragment de SupportMapFragment, et l'utiliser dans votre mise en page à la place. Vous pouvez alors remplacer Fragment#onreateview , et instancier votre MapView personnalisé là.

si cela ne fonctionne pas, vous pouvez toujours créer votre propre fragment - alors vous avez juste besoin de prendre soin d'appeler toutes les méthodes du cycle de vie vous-même (onCreate, onResume, etc). Cette réponse a un peu plus de détails.

0
répondu Ralf 2017-05-23 12:26:15
<ScrollView
            android:layout_width="match_parent"
    ::
    ::
    ::
      <FrameLayout
            android:id="@+id/map_add_business_one_rl"
            android:layout_width="match_parent"
            android:layout_height="100dp"
         >
                        <fragment

                            android:id="@+id/map"
                            android:name="com.google.android.gms.maps.SupportMapFragment"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:layout_marginTop="-100dp"
                            android:layout_marginBottom="-100dp"

                            />

        </FrameLayout>

    ::
    ::
    ::
     </ScrollView>
0
répondu Faakhir 2017-01-15 14:28:53