Google Maps Android API V2 使部分布局变黑
Posted
技术标签:
【中文标题】Google Maps Android API V2 使部分布局变黑【英文标题】:Google Maps Android API V2 blacking out part of layout 【发布时间】:2012-11-27 10:12:51 【问题描述】:我正在尝试将 Google Maps android API v2 集成到我的 Android 应用程序中。我将谷歌地图放在布局的中间。当布局能够适应屏幕时,它的效果很好,但是当布局太大而无法适应,并且用户向下滚动以查看其余内容时,布局的其余部分会被谷歌地图涂黑。请看以下截图:
(注意:所有地图手势都被禁用以允许用户滚动。)
我的布局 XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:scrollbars="vertical"
android:fillViewport="true" >
<RelativeLayout
android:layout_
android:layout_
android:orientation="vertical"
android:padding="20sp" >
<TextView
android:id="@+id/race_num"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
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>
我的 Activity 中的地图设置:
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】:我能够通过 hack 解决这个问题。我扩展了 ScrollView,以便我可以收到有关滚动事件的通知。我使用了来自Synchronise ScrollView scroll positions - android 的 ObservableScrollView 实现。
我添加到我的 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);
我试图使地图视图无效(),并仅切换地图视图的可见性,但都没有奏效。值得庆幸的是,切换整个视图的可见性不会导致任何闪烁或其他奇怪的行为。
可能有更好的解决方案,但在这一点上,这是我发现的唯一可行的方法。
【讨论】:
真的没有闪烁吗?我用 SlidngMenu 尝试了这个解决方案,但它没有改变任何东西。详情请见:***.com/questions/14419521/… 我在地图下有editTexts,我用了这个,接下来的编辑文本失去焦点,我该怎么做,或者有其他方法吗?【参考方案2】:我的解决方法:使用新的snapshot interface from 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 中的一个函数,其中我有一个名为“registeredFragments”的 SparseArray(Fragment)。
因此,无论何时滚动到地图或从地图滚动,您总会看到它的快照。这对我来说效果很好。
【讨论】:
【参考方案3】:通过覆盖 FragmentPagerAdapter 中的 onPageScrolled
,我能够针对 Viewpager 中的相同问题调整上述内容:
@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);
Viewpager 中的位置 0
是一个包含 MapFragment 的 Fragment,位置 1
是滚动后变黑的 Fragment。
【讨论】:
【参考方案4】:我的猜测是在 Activity 的初始化期间 MapFragment 的高度为 0。试试
<RelativeLayout
android:layout_
android:layout_
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>
【讨论】:
感谢您的建议。不幸的是,它没有用。我仍然有黑条,并且 lint 抛出了这个警告:这个 RelativeLayout 应该使用 android:layout_。还有其他想法吗? 只是作为一个实验 - 您是否尝试将有问题的 TextView 放在地图片段上方?当你这样做时会发生什么? 我已尝试移动 TextView。黑条仍然出现在地图下方,但由于布局较少(只有布局填充/边距),所以它更小。【参考方案5】:这应该通过使表面视图透明来解决它
https://github.com/NyxDigital/NiceSupportMapFragment
【讨论】:
【参考方案6】:另一种可能性是使用新的 GoogleMap.snapshot() 函数并使用地图的屏幕截图,如 here 所述。
【讨论】:
【参考方案7】:你可以使用这个库,
https://github.com/NyxDigital/NiceSupportMapFragment/
这对我来说很好。
【讨论】:
【参考方案8】:只是一个实验,但您是否尝试在 Map 初始化后在 setupMap() 中以编程方式将 TextView 添加到屏幕?
// 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)
【讨论】:
以上是关于Google Maps Android API V2 使部分布局变黑的主要内容,如果未能解决你的问题,请参考以下文章