【问题标题】:Android ActionBar turns black when loading Fragment with Google Map for the first time第一次用谷歌地图加载Fragment时Android ActionBar变黑
【发布时间】:2013-10-09 22:33:40
【问题描述】:

我有 Activity,我在其中创建了 DrawerLayout,其中我在侧边菜单中有 5 个条目,并且每个菜单条目正在加载其片段(在下面的代码中,您只会看到 3 个片段,这是因为最后两个菜单条目现在是虚拟的)。在那个活动上,我设置了我的自定义 ActionBar。 Activity 及其 onCreate 方法如下所示:

public class ActivityOffline extends ActionBarActivity implements OnPreferencesFragmentListener {
    final String[] fragments = { array with fragments path };

    private String[] drawerListViewItems;
    private DrawerLayout drawerLayout;
    private ListView drawerListView;
    private ActionBarDrawerToggle actionBarDrawerToggle;

    private Fragment mF1
    private Fragment mF2
    private Fragment mF3

    @SuppressLint("InlinedApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        setContentView(R.layout.activity_offline);

        mF1 = Fragment.instantiate(ActivityOffline.this, fragments[0]);
        mF2 = Fragment.instantiate(ActivityOffline.this, fragments[1]);
        mF3 = Fragment.instantiate(ActivityOffline.this, fragments[2]);

        LayoutInflater inflator = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflator.inflate(R.layout.action_bar_custom, null);

        final ActionBar actionBar = getSupportActionBar();

        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setCustomView(v, new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL
                | Gravity.FILL_HORIZONTAL));

        // Get list items from strings.xml
        drawerListViewItems = getResources().getStringArray(R.array.items);

        // Get ListView defined in activity_main.xml
        drawerListView = (ListView)findViewById(R.id.left_drawer);

        // App Icon
        drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);

        // Set the adapter for the list view
        drawerListView.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_listview_item, drawerListViewItems));

        FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
        tx.replace(R.id.content_frame, mF1);
        tx.commit();

        // Create ActionBarDrawerToggle
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);

        // Set actionBarDrawerToggle as the DrawerListener
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        // Еnable and show "up" arrow
        actionBar.setDisplayHomeAsUpEnabled(true);

        // Јust styling option
        drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        drawerListView.setOnItemClickListener(new DrawerItemClickListener());
    }
    }

当我在菜单项之间切换时,我总是像这样替换片段:

private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(@SuppressWarnings("rawtypes") AdapterView parent, View view, final int position, long id) {
            drawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
                @Override
                public void onDrawerClosed(View drawerView) {
                    super.onDrawerClosed(drawerView);

                    if (position < 3) {
                        FragmentTransaction tx = getSupportFragmentManager().beginTransaction();

                        switch (position) {
                        case 0:
                            tx.replace(R.id.content_frame, mF1);
                            break;
                        case 1:
                            tx.replace(R.id.content_frame, mF2);
                            break;
                        case 2:
                            tx.replace(R.id.content_frame, mF3);
                            break;
                        default:
                            tx.replace(R.id.content_frame, mF1);
                            break;
                        }

                        tx.commit();
                    }
                }
            });

            drawerLayout.closeDrawer(drawerListView);
        }
    }

所以,我的带有 Google Map 的 Fragment 是 mF2。它的实现和布局文件如下:

实施:

public class FragmentRouteView extends Fragment {
    static final LatLng MY_LOCATION = new LatLng(54.002858, 7.956872);

    private MapView mMapView;
    private GoogleMap mGoogleMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_route_view, container, false);
        mMapView = (MapView)v.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);
        mMapView.onResume();

        try {
            MapsInitializer.initialize(getActivity());
        }
        catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace();
        }

        mGoogleMap = mMapView.getMap();

        // Move the camera instantly to start point with a zoom of 15.
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MY_LOCATION, 15));

        // Zoom in, animating the camera.
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black" >

    <com.google.android.gms.maps.MapView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mapView"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

如果你问我为什么在布局文件中有这个视图 - 不要。它为我解决了一些问题,与我目前遇到的问题无关。

无论如何。介绍完之后,问题就来了:

当我第一次启动显示这些片段的活动并第一次导航到 mF2(具有 Google 地图)时,我看到了地图,但我的 ActionBar 全黑。没有标题,没有显示抽屉菜单的侧面按钮。另外,我在 Google 地图上看不到 + 和 - 标志。

这是预览:

但是,虽然操作栏是全黑的,但如果我按下菜单按钮应该在的地方,菜单显示和菜单按钮和标题会再次显示。

像这样:

之后,我在活动还活着的时候就再也没有遇到过这个问题。

然后一切正常,如下所示:

当活动被销毁并重新启动时,当我第一次使用 Google Map 导航到 mF2 时再次遇到此问题。

在装有 Android 4.x.x 的设备上不会发生这种情况。 它只发生在搭载 Android 2.x.x 的设备上。

知道是什么原因造成的吗?

为防止出现任何不相关的反问:

  • 是的,我正在以正确的方式使用支持库
  • 是的,我已正确设置 Google Maps API V2 密钥
  • 是的,当我从 Eclipse 启动设备上的应用程序时,我使用的是调试密钥
  • 为什么在我的地图片段布局中使用 RelativeLayout 而不仅仅是 com.google.android.gms.maps.MapView? - 我需要那个神奇的视图 出于某种原因,如果尝试使用 com.google.android.gms.maps.MapView 它也没有什么区别,同样的事情也会发生。

非常感谢。

[edit #1]:有一种情况是这个问题消失了:

我忘了添加这个:

如果我从我的 Maps Fragment 实现中注释掉这些行:

// Move the camera instantly to start point with a zoom of 15.
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MY_LOCATION, 15));

// Zoom in, animating the camera.
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

我看到 Google 地图以 (0,0) 坐标为中心,并且 ActionBar 显示正确。因此,当我对地图进行额外操作(缩放、定位、绘制标记等)时,似乎会出现此问题。

【问题讨论】:

    标签: android google-maps android-fragments android-actionbar google-maps-android-api-2


    【解决方案1】:

    存在一些已知问题([1][2][3])在 Maps API v2 视图顶部呈现 UI 项时会在 UI 项中产生一个黑框。

    这是来自 gmaps-api-issues issue #4659 的最新更新,截至 2013 年 8 月 27 日:

    我们刚刚推送了一个更新,将地图的基本视图更改为 Jelly Bean 4.1+ (API 16+) 设备上的 TextureView。这应该可以解决几个问题,包括在屏幕上移动地图视图时出现黑色矩形。

    TextureView 是在 Ice Cream Sandwich 中引入的,但我们发现许多 ICS 设备存在驱动程序问题和/或 TextureView 的错误实现。无法为这些设备或任何 ICS 之前的设备解析渲染工件。

    为确保您的地图可以使用 TextureView,需要对视图进行硬件加速。这可以在应用程序、活动或窗口级别完成。有关这方面的信息,请参阅 Android 的文档: http://developer.android.com/guide/topics/graphics/hardware-accel.html

    在 cmets 中报告了一些关于该问题的解决方法,您可能想尝试,但似乎无法解决 pre-ICS 设备上的潜在问题。

    【讨论】:

    • 看来你是对的。在某些设备上,它根本无法解决。我最终从片段切换到活动。无论如何,谢谢你的信息。干杯。
    猜你喜欢
    • 2013-03-30
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    相关资源
    最近更新 更多