API Android Google Maps V2, отменяющий часть макета
Я пытаюсь интегрировать Google Maps Android API v2 в свое приложение для Android. Я размещаю карту Google в середине моего макета. Он отлично работает, когда макет может поместиться на экране, но когда макет слишком большой, чтобы соответствовать, и пользователь прокручивает вниз, чтобы увидеть остальную часть содержимого, остальная часть макета затемняется Google Map. См. Следующий снимок экрана:
![Screenshot of the issue]()
(Примечание. Все жесты карты отключены, чтобы позволить пользователю прокручивать.)
Мой макет XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fillViewport="true" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20sp" >
<TextView
android:id="@+id/race_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="14sp"
android:textSize="@dimen/DetailsTop"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/race_in_chase" />
<TextView
android:id="@id/race_in_chase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/in_the_chase"
android:textSize="@dimen/DetailsTop"
android:background="@drawable/inthechase"
android:paddingLeft="20sp"
android:paddingRight="20sp"
android:visibility="gone"
android:layout_alignParentRight="true" />
<TextView
android:id="@+id/race_name"
style="@style/RaceDetailsName"
android:layout_below="@id/race_num" />
<TextView
android:id="@+id/race_track"
style="@style/RaceDetailsText"
android:paddingBottom="20sp"
android:layout_below="@id/race_name" />
<TextView
android:id="@+id/race_time"
style="@style/RaceDetailsText"
android:layout_below="@id/race_track" />
<TextView
android:id="@+id/race_tv"
style="@style/RaceDetailsText"
android:layout_below="@id/race_time" />
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="380dp"
android:layout_marginTop="20sp"
android:layout_marginBottom="20sp"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_below="@id/race_tv" />
<TextView
android:id="@+id/race_track_size"
style="@style/RaceDetailsText"
android:layout_below="@id/map" />
</RelativeLayout>
</ScrollView>
Моя настройка карты в моей деятельности:
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}
private static final LatLng CHICAGOLAND = new LatLng(41.474856, -88.056928);
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
mMap.getUiSettings().setZoomControlsEnabled(false);
mMap.getUiSettings().setAllGesturesEnabled(false);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(CHICAGOLAND)
.zoom(14.5f)
.bearing(53)
.build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
Моя догадка - это фрагмент карты, который не нравится ScrollView, поскольку макет, если он прекрасно, если весь макет подходит на экране, и прокрутка не требуется. Сама карта кажется правильным. Точечный размер точного размера остальных элементов в представлении. У кого-нибудь есть идеи, как я могу избавиться от затемнения под картой, чтобы я мог видеть TextView под ним? Все, что я пробовал до сих пор, не сработало.
Ответы
Ответ 1
Я смог обойти проблему с помощью взлома. Я расширил ScrollView, чтобы получать уведомления о событиях прокрутки. Я использовал реализацию ObservableScrollView из Синхронизировать позиции прокрутки ScrollView - андроид.
Я добавил в свой onCreate():
ObservableScrollView sv = (ObservableScrollView) findViewById(R.id.scroll);
sv.setScrollViewListener(this);
Затем, когда я получаю событие с изменением прокрутки, я переключаю видимость всего представления, что заставляет повторную компоновку, которая препятствует появлению черного ящика.
public void onScrollChanged(ObservableScrollView sv, int x, int y, int oldx, int oldy) {
sv.setVisibility(View.GONE);
sv.setVisibility(View.VISIBLE);
}
Я попытался сделать недействительным() отображение карты и переключить видимость только вида карты, но не работал. К счастью, просмотр видимости всего представления не вызывает какого-либо мерцания или другого странного поведения.
Вероятно, это лучшее решение, но на данный момент это единственное, что я нашел, который, похоже, работает.
Ответ 2
Мне удалось адаптировать вышеуказанное для той же проблемы в Viewpager, переопределив onPageScrolled
в FragmentPagerAdapter:
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
if ((position == 0 && positionOffsetPixels > 0) ||
(position == 1 && positionOffsetPixels == 0)) {
MyFragment blackedOutFragment = (MyFragment) getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":1");
if (blackedOutFragment != null) {
blackedOutFragment.getView().setVisibility(View.GONE);
blackedOutFragment.getView().setVisibility(View.VISIBLE);
}
}
}
Где позиция 0
в Viewpager - это фрагмент, содержащий MapFragment, а позиция 1
- это фрагмент, который затемняется после прокрутки.
Ответ 3
Мое обходное решение: используйте новый интерфейс моментального снимка из GoogleMap и отобразите снимок карты при прокрутке страницы.
Вот мой код для установки моментального снимка (он в том же фрагменте, что и карта, называемый FragmentMap.java):
public void setSnapshot(int visibility) {
switch(visibility) {
case View.GONE:
if(mapFragment.getView().getVisibility() == View.VISIBLE) {
getMap().snapshot(new SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap arg0) {
iv.setImageBitmap(arg0);
}
});
iv.setVisibility(View.VISIBLE);
mapFragment.getView().setVisibility(View.GONE);
}
break;
case View.VISIBLE:
if(mapFragment.getView().getVisibility() == View.GONE) {
mapFragment.getView().setVisibility(View.VISIBLE);
iv.setVisibility(View.GONE);
}
break;
}
}
Где "mapFragment" - это мой SupportedMapFragment, а "iv" - это ImageView (сделать его match_parent).
И вот я контролирую свиток:
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0 && positionOffsetPixels > 0 || position == 1 && positionOffsetPixels > 0) {
((FragmentMap)adapter.getRegisteredFragment(1)).setSnapshot(View.GONE);
} else if(position == 1 && positionOffsetPixels == 0) {
((FragmentMap)adapter.getRegisteredFragment(1)).setSnapshot(View.VISIBLE);
}
}
@Override
public void onPageScrollStateChanged(int arg0) {}
@Override
public void onPageSelected(int arg0) {}
});
Мой фрагмент с картой (FragmentMap) находится в позиции 1, поэтому мне нужно управлять прокруткой с позиции 0 до 1 и с позиции 1 на 2 (первое if-предложение). "getRegisteredFragment()" - это функция в моем пользовательском FragmentPagerAdapter, в котором у меня есть SparseArray (фрагмент), называемый зарегистрированными фрагментами.
Итак, всякий раз, когда вы переходите на или с вашей карты, вы всегда видите ее снимок. Это очень хорошо для меня.
Ответ 4
Я предполагаю, что высота MapFragment равна 0 во время инициализации Activity. Попробуйте
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="20sp" >
....
<TextView
android:id="@+id/race_track_size"
style="@style/RaceDetailsText"
android:layout_alignParentBottom="true"
android:layout_marginBottom="2dp"/>
</RelativeLayout>
Ответ 5
Просто эксперимент, но вы пытались добавить TextView на экран программно в setupMap() после того, как Карта уже была инициализирована?
// First, get a handle on the parent RelativeLayout,
// call it parentRelativeLayout, then…
TextView textView = new TextView(getActivity());
RelativeLayout.LayoutParams textLayout = new RelativeLayout.LayoutParams(
RelativeLayout.MATCH_PARENT,
RelativeLayout.MATCH_PARENT
);
textLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, -1);
textView.setLayoutParams(textLayout);
parentRelativeLayout.addView(textView)
Ответ 6
Это должно исправить это, сделав прозрачный вид на поверхности
https://github.com/NyxDigital/NiceSupportMapFragment
Ответ 7
Другая возможность - использовать новую функцию GoogleMap.snapshot() и вместо этого использовать скриншот карты, как описано здесь.
Ответ 8
Вы можете использовать эту библиотеку,
https://github.com/NyxDigital/NiceSupportMapFragment/
Эта работа прекрасна для меня.