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:
-
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.
-
Le point de vue n'utilise pas
requestDisallowInterceptTouchEvent()
lorsque l'utilisateur interagit avec la carte pour empêcher les touches d'interceptionScrollView
, donc si vous essayez de jouer à la verticale dans la carte, il effile juste le contenantScrollView
. Je pourrais théoriquement dériver une classe de vueMapView
et ajouter cette fonctionnalité, mais comment puis-je obtenirMapFragment
pour utiliser monMapView
personnalisé au lieu de celui standard?
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>
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..
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.
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;
}
}
});
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);
}
}
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.
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.
<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>