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 使部分布局变黑的主要内容,如果未能解决你的问题,请参考以下文章
Maps SDK for Android v.3.0.0 BETA "是否可以在没有Google Play服务的设备上运行?
Google Maps API v.3.31更新会破坏StageWebView和StageWebViewBridge
Google Maps Android API V2 检查 Google Maps 应用程序是不是被禁用
无法运行 Google Maps Android API Utility Demo