MapFragment в ScrollView
у меня есть один из новых MapFragment
С ScrollView
. На самом деле это SupportMapFragment
, но все равно. Это работает, но есть две проблемы:
при прокрутке, он оставляет позади черной маски. Черный цвет покрывает точно ту область, где была карта, за исключением отверстия, где были кнопки +/- zoom. Смотрите скриншот ниже. Это на Android 4.0.
вид не использует
requestDisallowInterceptTouchEvent()
когда пользователь взаимодействует с картой, чтобы предотвратить элементScrollView
перехват штрихов, так что если вы пытаетесь панорамировать вертикально на карте, он просто прокручивает содержащийScrollView
. Теоретически я мог бы получить класс представленияMapView
и добавить эту функциональность, но как я могу сделатьMapFragment
использовать мои индивидуальныеMapView
вместо стандартного?
8 ответов:
применение прозрачного изображения над фрагментом mapview, похоже, решает проблему. Это не самый красивый, но, кажется, работает. Вот фрагмент XML, который выглядит так:
<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>
для меня добавление прозрачного ImageView не помогло полностью удалить черную маску. Верхняя и нижняя части карты по-прежнему показывали черную маску при прокрутке.
так что решение для него я нашел в ответ С небольшим изменением. Я добавил
android:layout_marginTop="-100dp" android:layout_marginBottom="-100dp"
к моему фрагменту карты, так как это был вертикальный scrollview. Так что мой макет выглядел так:
<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>
для решения второй части вопроса я поставил
requestDisallowInterceptTouchEvent(true)
для меня главное ScrollView. Когда пользователь коснулся прозрачного изображения и переместился, я отключил прикосновение к прозрачному изображению дляMotionEvent.ACTION_DOWN
иMotionEvent.ACTION_MOVE
так что фрагмент карты может принимать сенсорные события.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; } } });
это работает для меня. Надеюсь, это поможет вам..
Это, вероятно, имеет свои корни в том же месте на причины проблемы в этот вопрос. Решение здесь заключается в использовании прозрачной рамки, которая немного легче по весу, чем прозрачное изображение.
сделано после большого количества исследований и разработок:
fragment_one.XML должен выглядеть так:
<?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>
ваш Java-класс FragmentOne.Ява выглядит так:
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; } } });
я использовал эти структуры, и я преодолел проблему.
я использовал вид контейнера для фрагмент карты.
<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>
контейнер класс:
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); } }
нет необходимости бороться с customScrollViews и прозрачными файлами макета. просто используйте более легкую версию карты google, и ваша проблема будет решена.
map:liteMode="true"
добавить выше свойство внутри фрагмента карты в файле макета. и вопрос будет исправлен.
для второй части вопроса-Вы можете получить класс фрагмента из SupportMapFragment и использовать его в своем макете вместо этого. Затем вы можете переопределить фрагмент#onCreateView, и создать экземпляр пользовательского вида карты там.
Если это не работает, вы всегда можете создать свой собственный фрагмент - тогда вам просто нужно позаботиться о вызове всех методов жизненного цикла самостоятельно (onCreate, onResume и т. д.). ответ есть еще некоторые детали.
<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>