MapFragment в ScrollView
У меня есть один из новых MapFragment
в ScrollView
. На самом деле это a SupportMapFragment
, но в любом случае. Он работает, но есть две проблемы:
-
При прокрутке он оставляет черную маску. Черные покрывают именно ту область, где была карта, за исключением отверстия, где были кнопки +/- масштабирования. См. Снимок экрана ниже. Это на Android 4.0.
-
В представлении не используется requestDisallowInterceptTouchEvent()
, когда пользователь взаимодействует с картой, чтобы предотвратить перехватывание ScrollView
, поэтому, если вы попытаетесь панорамировать по вертикали на карте, она просто прокручивает содержащую ScrollView
, Теоретически я мог бы получить класс представления MapView
и добавить эту функциональность, но как я могу получить MapFragment
для использования моего настроенного MapView
вместо стандартного?
![Partial screenshot of scrolling issue]()
Ответы
Ответ 1
Применение прозрачного изображения над фрагментом 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>
Ответ 2
Для меня добавление прозрачного 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;
}
}
});
Это сработало для меня. Надеюсь, это поможет вам.
Ответ 3
Это, вероятно, имеет свои корни в одном и том же месте по причине проблемы в этом вопросе. Решение заключается в использовании прозрачной рамки, которая немного меньше веса, чем прозрачное изображение.
Ответ 4
Готово после серии R & D:
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.java выглядит следующим образом:
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;
}
}
});
Ответ 5
Я использовал эти структуры, и я преодолел проблему.
Я использовал представление контейнера для фрагмента карты.
<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);
}
}
Ответ 6
Для второй части вопроса - вы можете получить класс фрагмента из SupportMapFragment и использовать его в своем макете. Затем вы можете переопределить Fragment # onCreateView и создать экземпляр своего настраиваемого MapView.
Если это не сработает, вы всегда можете создать свой собственный фрагмент - тогда вам просто нужно позаботиться о вызове всех методов жизненного цикла самостоятельно (onCreate, onResume и т.д.). Этот ответ содержит более подробную информацию.
Ответ 7
<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>
Ответ 8
Не нужно бороться с customScrollViews и прозрачными файлами макета. просто используйте более легкую версию google-карты, и ваша проблема будет решена.
map:liteMode="true"
добавить свойство внутри фрагмента карты в свой файл макета. и вопрос будет исправлен.