Ik heb een van de nieuwe MapFragment
en in een ScrollView
. Eigenlijk is het een SupportMapFragment
, maar toch. Het werkt, maar er zijn twee problemen:
-
Als je scrolt, blijft er een zwart masker achter. Het zwart dekt precies het gebied waar de kaart was, behalve een gat waar de +/- zoomknoppen zaten. Zie screenshot hieronder. Dit is op Android 4.0.
-
De weergave gebruikt
requestDisallowInterceptTouchEvent()
niet wanneer de gebruiker interactie heeft met de kaart om te voorkomen dat deScrollView
aanrakingen onderschept, dus als u verticaal probeert te pannen in de kaart, het scrolt gewoon de bevattendeScrollView
. Ik zou in theorie een weergaveklasseMapView
kunnen afleiden en die functionaliteit kunnen toevoegen, maar hoe kan ikMapFragment
ertoe brengen mijn aangepasteMapView
te gebruiken in plaats van de standaardversie ?
Antwoord 1, autoriteit 100%
Het lijkt het probleem op te lossen door een transparante afbeelding toe te passen op het mapview-fragment. Het is niet de mooiste, maar het lijkt te werken. Hier is een XML-fragment dat dit laat zien:
<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>
Antwoord 2, autoriteit 68%
Voor mij heeft het toevoegen van een transparante ImageView niet geholpen om het zwarte masker volledig te verwijderen. De bovenste en onderste delen van de kaart vertoonden nog steeds het zwarte masker tijdens het scrollen.
Dus de oplossing daarvoor vond ik in dit antwoord met een kleine verandering.
Ik heb toegevoegd,
android:layout_marginTop="-100dp"
android:layout_marginBottom="-100dp"
naar mijn kaartfragment omdat het verticale scrollview was. Dus mijn lay-out zag er nu zo uit:
<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>
Om het tweede deel van de vraag op te lossen heb ik requestDisallowInterceptTouchEvent(true)
ingesteld voor mijn hoofd ScrollView. Toen de gebruiker de transparante afbeelding aanraakte en bewoog, schakelde ik de aanraking van de transparante afbeelding uit voor MotionEvent.ACTION_DOWN
en MotionEvent.ACTION_MOVE
zodat het kaartfragment Touch Events kan opnemen.
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;
}
}
});
Dit werkte voor mij. Ik hoop dat het je helpt..
Antwoord 3, autoriteit 15%
Dit heeft waarschijnlijk zijn wortels op dezelfde plaats als de oorzaak van het probleem in deze vraag. De oplossing daar is om een transparant frame te gebruiken, dat iets lichter is dan een transparante afbeelding.
Antwoord 4, autoriteit 9%
Klaar na veel R&D:
fragment_one.xml zou er als volgt uit moeten zien:
<?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>
Uw Java-klasse van FragmentOne.java ziet er als volgt uit:
private GoogleMap mMap;
private MapView mapView;
private UiSettings mUiSettings;
private View customView
onCreateView
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;
}
}
});
Antwoord 5, autoriteit 4%
Ik heb deze structuren gebruikt en ik heb het probleem overwonnen.
Ik heb een containerweergave gebruikt voor kaartfragmenten.
<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>
De containerklasse:
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);
}
}
Antwoord 6, autoriteit 4%
Je hoeft niet te worstelen met customScrollViews en transparante lay-outbestanden. gebruik gewoon een lichtere versie van Google Maps en uw probleem zal worden opgelost.
map:liteMode="true"
voeg bovenstaande eigenschap toe in kaartfragment in uw lay-outbestand. en probleem zal worden opgelost.
Antwoord 7
Voor het tweede deel van de vraag: u kunt een fragmentklasse afleiden uit SupportMapFragment en die in plaats daarvan in uw lay-out gebruiken. U kunt dan Fragment#onCreateView, en start daar uw aangepaste MapView.
Als dat niet werkt, kun je altijd je eigen fragment maken – dan hoef je alleen maar zelf te zorgen voor het aanroepen van alle levenscyclusmethoden (onCreate, onResume, etc). Dit antwoordbevat meer details.
Antwoord 8
<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>