谷歌地图Android API V2黑屏部分布局

9
我正在尝试将Google Maps Android API v2集成到我的Android应用程序中。我将Google地图放置在我的布局中间。当布局适合屏幕时,它运行良好,但当布局太大而无法适应时,用户向下滚动以查看其余内容时,Google地图会将其余布局变为黑色。请参见以下截图:
(Note: 所有的地图手势都被禁用,以允许用户滚动.)
我的布局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>

我的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,因为如果整个布局适合屏幕且不需要滚动,则布局是fine的。地图本身似乎是正确的大小。黑屏是视图中剩余项目的确切大小。有人有任何想法如何摆脱地图下面的黑屏,以便我可以看到它下面的TextView吗?到目前为止,我尝试过的一切都没有起作用。

8个回答

2
我能够通过一个hack解决这个问题。我扩展了ScrollView,以便在滚动事件上得到通知。我使用了Synchronize 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);
}

我尝试使用invalidate()来使地图视图失效,以及仅切换地图视图的可见性,但都没有起作用。幸运的是,切换整个视图的可见性不会引起任何闪烁或其他奇怪的行为。
可能还有更好的解决方案,但目前这似乎是我找到的唯一有效的方法。

真的没有闪烁吗?我尝试了使用SlidngMenu的解决方案,但它并没有改变什么。详情请参见:https://dev59.com/rmYq5IYBdhLWcg3whQ40#koQGoYgBc1ULPQZF_Qdl - Michał Klimczak
我在地图下面有EditText,当我使用它时,下一个EditText会失去焦点,我该怎么做呢?或者还有其他方法吗? - JRowan

1
我能够通过在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。


1
我的解决方法:利用谷歌地图的新快照界面,在滚动页面时显示地图的快照。
以下是我设置快照的代码(它与地图位于同一片段中,名为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)。

因此,每当您滚动到或从地图滚动时,您总是会看到其快照。这对我非常有效。


0
我的猜测是在Activity初始化期间,MapFragment的高度为0。请尝试使用以下方法:
<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>

谢谢您的建议。不幸的是,它没有起作用。我仍然有黑色的条,并且lint会抛出此警告:此RelativeLayout应使用android:layout_height="wrap_content"。还有其他想法吗? - meisteg
只是作为一个实验 - 你尝试过将所讨论的 TextView 放在地图碎片上方吗?当你这样做时会发生什么? - DiscDev
我已经尝试移动TextView。黑色条仍然出现在地图下方,但由于布局较少(仅有布局填充/边距),它变得更小了。 - meisteg

0

另一种可能性是使用新的 GoogleMap.snapshot() 函数,并像 这里 描述的那样使用地图的截图。


0

0

这只是一个实验性的问题,但你是否曾尝试在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)

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接