使用导航抽屉中的片段覆盖活动

时间:2014-05-26 20:50:09

标签: android android-fragments navigation-drawer

我无法在现有活动的基础上放置片段。我想要完成的内容如下:打开应用程序 - > mapView已创建 - >导航抽屉已创建 - >导航抽屉上的按钮打开放在mapView顶部的新片段(而mapView不可见)。发生了什么是片段的布局显示,但布局的白色空间是透明的,我仍然可以使用地图。这是我的代码:

MainActivity.java

public class MainActivity extends Activity {

 private MapView mapView;
 private LocationListener locationListener;
 private GeometryLayer locationLayer; 
 private Timer locationTimer;

 private DrawerLayout mDrawerLayout;
 private ListView mDrawerList;
 private ActionBarDrawerToggle mDrawerToggle;

 private CharSequence mDrawerTitle;
 private CharSequence mTitle;
 CustomDrawerAdapter adapter;

 List<DrawerItem> dataList;

 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     setMap();

     initDrawer(savedInstanceState);

 }

 private class DrawerItemClickListener implements ListView.OnItemClickListener {
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         SelectItem(position);

     }
 }

 @Override
 public void setTitle(CharSequence title) {
       mTitle = title;
       getActionBar().setTitle(mTitle);
 }

 @Override
 protected void onPostCreate(Bundle savedInstanceState) {
       super.onPostCreate(savedInstanceState);
       // Sync the toggle state after onRestoreInstanceState has occurred.
       mDrawerToggle.syncState();
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
       // The action bar home/up action should open or close the drawer.
       // ActionBarDrawerToggle will take care of this.
       if (mDrawerToggle.onOptionsItemSelected(item)) {
             return true;
       }

       return false;
 }

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
       super.onConfigurationChanged(newConfig);
       // Pass any configuration change to the drawer toggles
       mDrawerToggle.onConfigurationChanged(newConfig);
 }

 public void SelectItem(int possition) {

     Fragment fragment = null;
     Bundle args = new Bundle();
     switch (possition) {

     case 0:
         fragment = new ProfileFragment();
         args.putString(ProfileFragment.ITEM_NAME, dataList.get(possition)
                     .getItemName());
         args.putInt(ProfileFragment.IMAGE_RESOURCE_ID, dataList.get(possition)
                     .getImgResID());

         break;

     case 1:
           fragment = new ProfileFragment();
           args.putString(ProfileFragment.ITEM_NAME, dataList.get(possition)
                       .getItemName());
           args.putInt(ProfileFragment.IMAGE_RESOURCE_ID, dataList.get(possition)
                       .getImgResID());

           break;

     case 4:
           fragment = new SettingsFragment();
           args.putString(SettingsFragment.ITEM_NAME, dataList.get(possition)
                       .getItemName());
           args.putInt(SettingsFragment.IMAGE_RESOURCE_ID, dataList.get(possition)
                       .getImgResID());
           break;

     default:
           break;
     }

     fragment.setArguments(args);
     android.app.FragmentManager frgManager = getFragmentManager();
     frgManager.beginTransaction().replace(R.id.content_frame, fragment)
                 .commit();

     mDrawerList.setItemChecked(possition, true);
     setTitle(dataList.get(possition).getItemName());
     mDrawerLayout.closeDrawer(mDrawerList);

}

 @Override
 protected void onStart() {
     super.onStart();

     // 4. Start the map - mandatory.
     mapView.startMapping();

     // Create layer for location circle
     locationLayer = new GeometryLayer(mapView.getLayers().getBaseProjection());
     mapView.getComponents().layers.addLayer(locationLayer);

     // add GPS My Location functionality 
     final MyLocationCircle locationCircle = new MyLocationCircle(locationLayer);
     initGps(locationCircle);

     // Run animation
     locationTimer = new Timer();
     locationTimer.scheduleAtFixedRate(new TimerTask() {
         @Override
         public void run() {
             locationCircle.update(mapView.getZoom());
         }
     }, 0, 50);
 }

 @Override
 protected void onStop() {
     // Stop animation
     locationTimer.cancel();

     // Remove created layer
     mapView.getComponents().layers.removeLayer(locationLayer);

     // remove GPS support, otherwise we will leak memory
     deinitGps();

     // Note: it is recommended to move startMapping() call to onStart method and implement onStop method (call MapView.stopMapping() from onStop). 
     mapView.stopMapping();

     super.onStop();
}

 @Override
 protected void onDestroy() {
     super.onDestroy();
 }

 protected void initGps(final MyLocationCircle locationCircle) {
     final Projection proj = mapView.getLayers().getBaseLayer().getProjection();

     locationListener = new LocationListener() {
         @Override
         public void onLocationChanged(Location location) {
              locationCircle.setLocation(proj, location);
              locationCircle.setVisible(true);

              // recenter automatically to GPS point
              // TODO in real app it can be annoying this way, add extra control that it is done only once
              mapView.setFocusPoint(mapView.getLayers().getBaseProjection().fromWgs84(location.getLongitude(), location.getLatitude()));
         }

         @Override
         public void onStatusChanged(String provider, int status, Bundle extras) {
             Log.debug("GPS onStatusChanged "+provider+" to "+status);
         }

         @Override
         public void onProviderEnabled(String provider) {
             Log.debug("GPS onProviderEnabled");
         }

         @Override
         public void onProviderDisabled(String provider) {
             Log.debug("GPS onProviderDisabled");
         }
     };

     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
     List<String> providers = locationManager.getProviders(true);
     for(String provider : providers){
         locationManager.requestLocationUpdates(provider, 10000, 100, locationListener);
     }

 }

 protected void deinitGps() {
     // remove listeners from location manager - otherwise we will leak memory
     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
     locationManager.removeUpdates(locationListener);    
 }

 // adjust zooming to DPI, so texts on rasters will be not too small
 // useful for non-retina rasters, they would look like "digitally zoomed"
 private void adjustMapDpi() {
     DisplayMetrics metrics = new DisplayMetrics();
     getWindowManager().getDefaultDisplay().getMetrics(metrics);
     float dpi = metrics.densityDpi;
     // following is equal to  -log2(dpi / DEFAULT_DPI)
     float adjustment = (float) - (Math.log(dpi / DisplayMetrics.DENSITY_HIGH) / Math.log(2));
     Log.debug("adjust DPI = "+dpi+" as zoom adjustment = "+adjustment);
     mapView.getOptions().setTileZoomLevelBias(adjustment / 2.0f);
 }

 private void addCartoDbLayer() {

        //  5.1 Define styles for all possible geometry types
        int color = Color.BLUE;
        int minZoom = 5;

        final Bitmap pointMarker = UnscaledBitmapLoader.decodeResource(getResources(), R.drawable.point);
        final StyleSet<PointStyle> pointStyleSet = new StyleSet<PointStyle>();
        PointStyle pointStyle = PointStyle.builder().setBitmap(pointMarker).setSize(0.05f).setColor(color).setPickingSize(0.2f).build();
        pointStyleSet.setZoomStyle(minZoom, pointStyle);

        final StyleSet<LineStyle> lineStyleSet = new StyleSet<LineStyle>();
        LineStyle lineStyle = LineStyle.builder().setWidth(0.04f).setColor(Color.WHITE).build();
        lineStyleSet.setZoomStyle(minZoom, lineStyle);

        final StyleSet<PolygonStyle> polygonStyleSet = new StyleSet<PolygonStyle>(null);
        PolygonStyle polygonStyle = PolygonStyle.builder().setColor(0xFFFF6600 & 0x80FFFFFF).setLineStyle(lineStyle).build();
        polygonStyleSet.setZoomStyle(minZoom, polygonStyle);

        String account = "bitciv";
        String table = "units"; // kihelkonnad_1897, maakond_20120701
        String columns = "cartodb_id,name,iso2,pop2005,area,the_geom_webmercator"; // NB! always include cartodb_id and the_geom_webmercator
        //String columns = "cartodb_id,job,the_geom_webmercator";
        int limit = 5000; // max number of objects
        String sql = "SELECT "+columns+" FROM "+table+" WHERE the_geom_webmercator && ST_SetSRID('BOX3D(!bbox!)'::box3d, 3857) LIMIT "+limit;

        //      String sql2 = "SELECT name, type, oneway, osm_id, the_geom_webmercator FROM osm_roads WHERE type in ('trunk','primary') AND the_geom_webmercator && ST_SetSRID('BOX3D(!bbox!)'::box3d, 3857) LIMIT 500";
        //      String sql2 = "SELECT name, type, oneway, osm_id, the_geom_webmercator FROM osm_roads WHERE the_geom_webmercator && ST_SetSRID('BOX3D(!bbox!)'::box3d, 3857) LIMIT 500";

        CartoDbDataSource cartoDataSource = new CartoDbDataSource(mapView.getLayers().getBaseLayer().getProjection(), account, sql) {

            @Override
            protected Label createLabel(Map<String, String> userData) {
                StringBuffer labelTxt = new StringBuffer();
                for (Map.Entry<String, String> entry : userData.entrySet()){
                    labelTxt.append(entry.getKey() + ": " + entry.getValue() + "\n");
                }
                return new DefaultLabel("Data:", labelTxt.toString());
            }

            @Override
            protected StyleSet<PointStyle> createPointStyleSet(Map<String, String> userData, int zoom) {
                return pointStyleSet;
            }

            @Override
            protected StyleSet<LineStyle> createLineStyleSet(Map<String, String> userData, int zoom) {
                return lineStyleSet;
            }

            @Override
            protected StyleSet<PolygonStyle> createPolygonStyleSet(Map<String, String> userData, int zoom) {
                return polygonStyleSet;
            }

        };

        GeometryLayer cartoLayerTrunk = new GeometryLayer(cartoDataSource);
        mapView.getLayers().addLayer(cartoLayerTrunk);

    }

 private void setMap(){

    // enable logging for troubleshooting - optional
     Log.enableAll();
     Log.setTag("hellomap");

     // 1. Get the MapView from the Layout xml - mandatory
     mapView = (MapView) findViewById(R.id.mapView);

     // Optional, but very useful: restore map state during device rotation,
     // it is saved in onRetainNonConfigurationInstance() below
     Components retainObject = (Components) getLastNonConfigurationInstance();
     if (retainObject != null) {
         // just restore configuration and update listener, skip other initializations
         mapView.setComponents(retainObject);
         return;
     } else {
         // 2. create and set MapView components - mandatory
         mapView.setComponents(new Components());
     }

     // 3. Define map layer for basemap - mandatory.
     // Here we use MapQuest open tiles.
     // We use online data source for the tiles and the URL is given as template. Almost all online tiled maps use EPSG3857 projection.
     RasterDataSource dataSource = new HTTPRasterDataSource(new EPSG3857(), 0, 18, "http://otile1.mqcdn.com/tiles/1.0.0/osm/{zoom}/{x}/{y}.png");

     RasterLayer mapLayer = new RasterLayer(dataSource, 0);

     mapView.getLayers().setBaseLayer(mapLayer);

     adjustMapDpi();

     // Show performance indicator
     //mapView.getOptions().setFPSIndicator(true);

     // Increase raster tile download speed by doing 4 downloads in parallel
     //mapView.getOptions().setRasterTaskPoolSize(4);

     // set initial map view camera - optional. "World view" is default
     // Location: San Francisco 
     // NB! it must be in base layer projection (EPSG3857), so we convert it from lat and long
     mapView.setFocusPoint(mapView.getLayers().getBaseLayer().getProjection().fromWgs84(-122.41666666667f, 37.76666666666f));
     // rotation - 0 = north-up
     mapView.setMapRotation(0f);
     // zoom - 0 = world, like on most web maps
     mapView.setZoom(16.0f);
     // tilt means perspective view. Default is 90 degrees for "normal" 2D map view, minimum allowed is 30 degrees.
     mapView.setTilt(65.0f);

     // Activate some mapview options to make it smoother - optional
     mapView.getOptions().setPreloading(true);
     mapView.getOptions().setSeamlessHorizontalPan(true);
     mapView.getOptions().setTileFading(true);
     mapView.getOptions().setKineticPanning(true);
     mapView.getOptions().setDoubleClickZoomIn(true);
     mapView.getOptions().setDualClickZoomOut(true);

     // set sky bitmap - optional, default - white
     mapView.getOptions().setSkyDrawMode(Options.DRAW_BITMAP);
     mapView.getOptions().setSkyOffset(4.86f);
     mapView.getOptions().setSkyBitmap(
             UnscaledBitmapLoader.decodeResource(getResources(),
                     R.drawable.sky_small));

     // Map background, visible if no map tiles loaded - optional, default - white
     mapView.getOptions().setBackgroundPlaneDrawMode(Options.DRAW_BITMAP);
     mapView.getOptions().setBackgroundPlaneBitmap(
             UnscaledBitmapLoader.decodeResource(getResources(),
                     R.drawable.background_plane));
     mapView.getOptions().setClearColor(Color.WHITE);

     // configure texture caching - optional, suggested 
     mapView.getOptions().setTextureMemoryCacheSize(40 * 1024 * 1024);
     mapView.getOptions().setCompressedMemoryCacheSize(8 * 1024 * 1024);

     // define online map persistent caching - optional, suggested. Default - no caching
     mapView.getOptions().setPersistentCachePath(this.getDatabasePath("mapcache").getPath());
     // set persistent raster cache limit to 100MB
     mapView.getOptions().setPersistentCacheSize(100 * 1024 * 1024);

    /* // 5. Add simple marker to map. 
     // define marker style (image, size, color)
     Bitmap pointMarker = UnscaledBitmapLoader.decodeResource(getResources(), R.drawable.olmarker);
     MarkerStyle markerStyle = MarkerStyle.builder().setBitmap(pointMarker).setSize(0.5f).setColor(Color.WHITE).build();

     // define label what is shown when you click on marker
     Label markerLabel = new DefaultLabel("San Francisco", "Here is a marker");

     // define location of the marker, it must be converted to base map coordinate system
     MapPos markerLocation = mapLayer.getProjection().fromWgs84(-122.416667f, 37.766667f);

     // create layer and add object to the layer, finally add layer to the map. 
     // All overlay layers must be same projection as base layer, so we reuse it
     MarkerLayer markerLayer = new MarkerLayer(mapLayer.getProjection());
     markerLayer.add(new Marker(markerLocation, markerLabel, markerStyle, null));
     mapView.getLayers().addLayer(markerLayer); */

     // add event listener
     MyMapEventListener mapListener = new MyMapEventListener(this, mapView);
     mapView.getOptions().setMapListener(mapListener);

     // 5. Add CartoDB vector layer to map
     addCartoDbLayer();

 }

 private void initDrawer(Bundle savedInstanceState){

    // Initializing
     dataList = new ArrayList<DrawerItem>();
     mTitle = mDrawerTitle = getTitle();
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
     mDrawerList = (ListView) findViewById(R.id.left_drawer);

     mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
                 GravityCompat.START);
     mDrawerList.setBackgroundResource(R.color.white);

     // Add Drawer Item to dataList
     dataList.add(new DrawerItem("Profile", R.drawable.ic_action_email));
     dataList.add(new DrawerItem("Messages", R.drawable.ic_action_good));
     dataList.add(new DrawerItem("Statistics", R.drawable.ic_action_gamepad));
     dataList.add(new DrawerItem("Settings", R.drawable.ic_action_labels));
     dataList.add(new DrawerItem("Invite", R.drawable.ic_action_search));

     adapter = new CustomDrawerAdapter(this, R.layout.custom_drawer_item,
             dataList);

     mDrawerList.setAdapter(adapter);

     mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

     getActionBar().setDisplayHomeAsUpEnabled(true);
     getActionBar().setHomeButtonEnabled(true);

     mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                 R.drawable.ic_drawer, R.string.drawer_open,
                 R.string.drawer_close) {
           public void onDrawerClosed(View view) {
                 getActionBar().setTitle(mTitle);
                 invalidateOptionsMenu(); // creates call to
                                                           // onPrepareOptionsMenu()
           }

           public void onDrawerOpened(View drawerView) {
                 getActionBar().setTitle(mDrawerTitle);
                 invalidateOptionsMenu(); // creates call to
                                                           // onPrepareOptionsMenu()
           }
     };

     mDrawerLayout.setDrawerListener(mDrawerToggle);

     if (savedInstanceState == null) {
           SelectItem(0);
     }

 }
}

activity_main.xml中

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- The main content view -->

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.nutiteq.MapView
    android:id="@+id/mapView"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" />

</FrameLayout>

<!-- The navigation drawer -->

<ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#111"/>



</android.support.v4.widget.DrawerLayout>

1 个答案:

答案 0 :(得分:0)

如果我理解正确,发生的事情是最顶层Fragment的空格不会捕获点击事件。要解决此问题,您需要使最高ViewGroup可点击的根Fragment。如果要添加的第二个Fragment占据整个或大部分屏幕,最好在remove()中调用add()而不是FragmentTransaction,以完全避免此问题