I am using Nutiteq SDK which holds a MapView and am trying to use a navigation drawer as well. The problem I am having is that whenever I slide from the left or click the icon to open the drawer nothing opens, but I am unable to move the map until I slide the drawer back or click the icon again. This has lead me to believe that the drawer is opening but not displaying. Here is my MainActivity.java and activity_main.xml:
MainActivity.java
public class MainActivity extends Activity {
private MapView mapView;
private LocationListener locationListener;
private GeometryLayer locationLayer;
private Timer locationTimer;
private String[] drawerListViewItems;
private ListView drawerListView;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle actionBarDrawerToggle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setMap();
// 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);
// Set the adapter for the list view
drawerListView.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_listview_item, drawerListViewItems));
// App Icon
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
);
// Set actionBarDrawerToggle as the DrawerListener
drawerLayout.setDrawerListener(actionBarDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
// just styling option add shadow the right edge of the drawer
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
actionBarDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// call ActionBarDrawerToggle.onOptionsItemSelected(), if it returns true
// then it has handled the app icon touch event
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public Object onRetainNonConfigurationInstance() {
Log.debug("onRetainNonConfigurationInstance");
return this.mapView.getComponents();
}
@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 onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
actionBarDrawerToggle.syncState();
}
@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();
}
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>
I tried same with Android Drawer sample app, and replaced ImageView with MapView. This works fine for me, see screenshot below. Maybe the problem is that you put MapView directly to main Layout? Please try via Fragment like in the sample app.
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With