带有Google Maps API v2的ViewPager:神秘的黑色视图


95

我已经将新的Google Maps api v2片段集成到了视图传呼器中。从地图片段滚动时,黑色视图会与相邻片段重叠。有人解决了吗?

编辑:屏幕截图

在此处输入图片说明

public static class PagerAdapter extends FragmentPagerAdapter{

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    @Override
    public Fragment getItem(int position) {

        Fragment pageFragment;

        switch (position) {
        case 0:
            pageFragment = new TabAFragment();
            break;

        case 1:
            pageFragment = new TabBFragment();
            break;

        case 2:
            pageFragment = SupportMapFragment.newInstance();
            break;

        default:
            pageFragment = null;
            break;
        }

        return pageFragment;
    }
}

它会发生在一个以上的设备上吗?也许您从ViewPager获得了一些代码行,并且地图实现可能有助于更好地了解您的问题。
阿迪尼亚2012年

是的,在我尝试过的所有设备上都发生过:三星,htc,android 4.0、2.3等。
Pepe 2012年

@Pepe,请问您如何从中获取GoogleMap对象ViewPager?坚持了几个星期。如果您对问题的理解不充分,请查找我的问题,即可找到我的帖子。请回复。
azizbekian

我想补充一点,当做一个screen record问题似乎没有发生。
theblang

Answers:


115

通过将另一个具有透明背景的视图放置在ViewPager内部的顶部,我能够停止过渡后留下的黑色表面FrameLayout

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>

    <!-- hack to fix ugly black artefact with maps v2 -->
    <FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:background="@android:color/transparent" />

</FrameLayout>

1
大!这不是完美的,因为有时在移动寻呼机时会出现在黑色视图中。但是现在它不再保留在屏幕上了。谢谢!(您对此骇客有什么解释吗?)
Pepe

7
并不是的。我只是注意到缩放和位置控件位于地图表面顶部的位置上,没有出现黑迹,因此我在顶部放置了一个视图以覆盖整个地图,并且它起作用了。我同意这并不完美-黑色背景似乎是GLSurfaceView窗口的一部分code.google.com/p/gmaps-api-issues/issues/detail?id=4639
Jeff Gilfelt 2012年

5
似乎它解决了我的ViewPager问题。谢谢,但是看来我有一个类似的问题,有一个SlideMenu(像G + / Yahoo这样的左菜单),做了同样的事情。关于修复SlideMenu实现有什么想法吗?
Chrispix

@Chrispix不为容器设置动画,仅在侧面菜单上使用动画,它已为我修复。
meh 2012

1
我已经完成了此操作并使用了以下编程解决方案,它们可以在应用程序处于前台状态时工作,但是当应用程序关闭并仍在运行时,您又回到地图上时,地图仍会停留在最上面
。– L7ColWinters

43

SlidingMenu和ViewPager遇到相同的问题。我注意到地图片段中的控件按钮在左侧工件中不是黑色的。我通过重写onCreateView()方法解决了问题MapFragment (SupportMapFragment)

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup view, 
                         Bundle savedInstance) {

    View layout = super.onCreateView(inflater, view, savedInstance);
    FrameLayout frameLayout = new FrameLayout(getActivity());
    frameLayout.setBackgroundColor(
        getResources().getColor(android.R.color.transparent));
    ((ViewGroup) layout).addView(frameLayout,
        new ViewGroup.LayoutParams(
            LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT
        )
    );
    return layout;
}

我也将它用于SlidingMenu。但是我有闪烁的问题(带有滑动动画),这是不可接受的,看起来很糟糕。你也有吗 我上的HTC One S.测试有趣的是,我只收盘SlidingMenu当有这个问题与开场动画,而不是
米哈尔ķ

没有一个修复程序对我有用。我实际上遇到了与Michal K相同的问题。使用SlidingMenu并以连续的速度缓慢打开或关闭,没有问题。滑动打开或按回去以关闭窗口,看起来地图滞后了一点,直到幻灯片结束,在此地图返回其正确位置为止。
qubz

@qubz:关于“滑动菜单”,请尝试使菜单(而非地图)动起来。如果地图没有移动,它为我解决了问题。
2013年

@meh:当我打开/关闭SlidingMenu时,地图可能正在移动。移动是指CameraUpdate。我将查看是否可以暂停动画,尽管这会阻碍UX。
qubz

@Lubos Horacek:您能发布一个示例代码。我收到了Null指针异常错误..
avinash

7

Google为此发布了一个修复程序,但仅针对4.1+版本(您无需下载新版本的PlayServices,它们使用了服务器端标志)

这就是我用来绕过此问题的方法-确保您不会浪费任何CPU周期大于等于4.1的设备

public class FixMapFragment extends SupportMapFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, 
                             ViewGroup container, 
                             Bundle savedInstanceState) {

        View view = super.onCreateView(inflater, container, savedInstanceState);

        // Fix for black background on devices < 4.1
        if (android.os.Build.VERSION.SDK_INT < 
            android.os.Build.VERSION_CODES.JELLY_BEAN) {
            setMapTransparent((ViewGroup) view);
        }
        return view;
    }

    private void setMapTransparent(ViewGroup group) {
        int childCount = group.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = group.getChildAt(i);
            if (child instanceof ViewGroup) {
                setMapTransparent((ViewGroup) child);
            } else if (child instanceof SurfaceView) {
                child.setBackgroundColor(0x00000000);
            }
        }
    }
}

我猜您按如下方式引用该类:FixMapFragment mapFragment = (FixMapFragment) fragmentManager.findFragmentById(R.id.map);并在布局文件中:<fragment android:id="@+id/map" android:name="com.example.fragments.FixMapFragment" ...。不过,据我所知(Android 4.0.4),地图仍然会闪烁。
JJD

@JJD我有一个闪烁的mapview,有没有办法解决?
Rat-a-t-a-tat Ratatouille 2014年

据我所知,没有可靠的解决方法来避免地图视图闪烁。
JJD 2014年

我不知道我现在所做的是否正确,但是可以。我将地图视图的可见性设置为不可见,然后在几秒钟后将地图视图的可见性设置回可见。减少闪烁。
Rat-a-t-a-tat Ratatouille 2014年

6

我的解决方法:使用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) {}
    });

我的带有map(FragmentMap)的片段位于位置1,因此我需要控制从位置0到1以及从位置1到2(第一个if子句)的滚动。“ getRegisteredFragment()”是自定义FragmentPagerAdapter中的一个函数,其中有一个名为“ registeredFragments”的SparseArray(Fragment)。

因此,每当滚动到地图或从地图上滚动时,总会看到它的快照。这对我来说很好。


其他答案对我不起作用-这是唯一有效的答案。谢谢!
alice_silver_man 2014年

4

我在滚动列表视图时遇到了黑屏的同样问题,我在同一屏幕中使用带有列表视图的地图片段,我已经在xml中使用魔法属性解决了这个问题,我只是在谈论列表视图,我们只好把android: scrollingCache =“ false” .my问题已修复,请尝试使用此属性停止在地图中滞后和闪烁。


2

您没有提供太多细节,所以我只能建议太多。我有一个类似的问题,即在寻呼机的视图之间屏幕闪烁。原来是第一次在页面之间切换时mapView膨胀。

需要明确的是,我的寻呼机有3页,而地图是最后一页。

为了解决这个问题,我发现将屏幕外页面的数量设置为2(在上面的例子中是可行的),当我的片段开始时,它会立即加载所有视图。

请参阅http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int


谢谢,但是没有用。问题在于,地图所覆盖的屏幕部分在更改为其他片段时仍保持黑色,覆盖了该另一个片段的视图。
Pepe 2012年

嗯,有趣。我对此有一个思考。
格雷厄姆·史密斯

我在链接到
mplungjan

0

有另一种解决方案。我正在另一个片段中显示MapFragment。MapFragment被动态添加到FrameLayout中。

解决方案是在滑动菜单的打开和关闭事件上使用frameLayout.setVisibility(View.Visible)和frameLayout.setVisibility(View.Gone)。需要添加额外的视图。黑色区域完全消失了。

getSlidingMenu().setOnOpenListener(
        new OnOpenListener() {
            @Override
            public void onOpen() {
                frameLayout.setVisibility(View.GONE);
            }
        });

getSlidingMenu().setOnClosedListener(
        new OnClosedListener() {

            @Override
            public void onClosed() {
                frameLayout.setVisibility(View.VISIBLE);
            }
        });

0

上面的方法都不适合我,甚至其他地方也找不到。最后,我选择了部分解决方案。我通过ViewPager的onPageChangeListener监听页面更改,并在地图页面开始滚动时隐藏地图,同样在地图停止滚动时再次显示地图。我还添加了滚动时要显示的白色视图。


可以进一步扩展它,以将View的当前图像捕获到位图,然后在滚动寻呼机时将其显示在ImageView上。这样,用户就不会注意到它背后的黑客。但是,我发现此计算过于昂贵,因为它将减慢UI对刷卡的响应。
azyoot

-2

只需将我的自定义地图片段复制到您的项目中即可。如果您有黑线,并且ScrollView的顶部和底部设置为ScrollView,则android:fadingEdge =“ none”

public class CustomMapFragment extends SupportMapFragment {
private OnActivityCreatedListener onActivityCreatedListener;

public CustomMapFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup view, Bundle savedInstance) {
    View layout = super.onCreateView(inflater, view, savedInstance);

    FrameLayout frameLayout = new FrameLayout(getActivity());
    frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));
    ((ViewGroup) layout).addView(frameLayout,
            new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    return layout;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (getOnActivityCreatedListener() != null)
        getOnActivityCreatedListener().onCreated();
}

public OnActivityCreatedListener getOnActivityCreatedListener() {
    return onActivityCreatedListener;
}

public void setOnActivityCreatedListener(
        OnActivityCreatedListener onActivityCreatedListener) {
    this.onActivityCreatedListener = onActivityCreatedListener;
}

public interface OnActivityCreatedListener {
    void onCreated();
}

}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.