Cannot use MapView in a LinearLayout

1230
3
Jump to solution
06-25-2012 10:46 PM
StephenQuan
Occasional Contributor
I am having two issues when I place a MapView control in a LinearLayout (i.e. useLinearLayout = true😞

1. The MapView no longer renders properly. It renders black. If a show a popup Toast, the MapView renders temporarily then goes black again.
2. The MapView no longer generates OnSingleTapListener() events.

If I setContentView() on the MapView control, everything works fine (i.e. useLinearLayout = false).

The reason why I want to use a LinearLayout is I want to add other UI controls to my Activity, such as a Button.

The following code demonstrate the above symptoms.
It is based on the Hello World Map sample.
By setting useLinearLayout to true or false will cause the either of the above two symptoms to occur.

I get these symptoms on both SDK 1.0.1 and SDK 2.0.0.

package com.esri.android.editdemo;  import com.esri.android.map.GraphicsLayer; import com.esri.android.map.MapView; import com.esri.android.map.ags.ArcGISTiledMapServiceLayer; import com.esri.android.map.event.OnSingleTapListener; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.GeometryEngine; import com.esri.core.geometry.Point; import com.esri.core.geometry.SpatialReference; import com.esri.core.map.Graphic; import com.esri.core.symbol.SimpleMarkerSymbol;  import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast;  public class EditDemoActivity extends Activity {  LinearLayout linearLayout = null;  MapView map = null;  GraphicsLayer graphicsLayer = null;  SpatialReference webMercator = SpatialReference.create(102100);    public void onCreate(Bundle savedInstanceState)  {   super.onCreate(savedInstanceState);    final Context context = this;      boolean useLinearLayout = true; // <-- mapView fails, but has button   // boolean useLinearLayout = false; // <-- mapView works, but no button   if (useLinearLayout)   {    linearLayout = new LinearLayout(this);    linearLayout.setOrientation(LinearLayout.VERTICAL);    setContentView(linearLayout);    Button testButton = new Button(this);    testButton.setText("Hello");    testButton.setOnClickListener(new OnClickListener()    {     public void onClick(View v)     {      Toast.makeText(context, "Test", Toast.LENGTH_SHORT).show();     }    });    linearLayout.addView(testButton);    map = new MapView(this);    linearLayout.addView(map);   }   else   {    map = new MapView(this);    setContentView(map);   }      // Add the ArcGIS Online layer to the map.   map.addLayer(new ArcGISTiledMapServiceLayer("" +   "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));   map.setOnSingleTapListener(new OnSingleTapListener()   {    public void onSingleTap(float x, float y)    {     Point newPoint = map.toMapPoint(new Point(x, y));     SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(Color.RED, 20, SimpleMarkerSymbol.STYLE.CIRCLE);     graphicsLayer.addGraphic(new Graphic(newPoint, simpleMarkerSymbol));    }   });     // Set the extent to ESRI Redlands Campus   Point minPoint = GeometryEngine.project(-117.200, 34.057, webMercator);   Point maxPoint = GeometryEngine.project(-117.198, 34.059, webMercator);   Envelope extent = new Envelope(minPoint.getX(), minPoint.getY(), maxPoint.getX(), maxPoint.getY());   extent.inflate(10000, 10000);   map.setExtent(extent);    // Create a graphics layer and add it to the map.   graphicsLayer = new GraphicsLayer();   map.addLayer(graphicsLayer);  }   protected void onPause()  {   super.onPause();   map.pause();  }   protected void onResume()  {   super.onResume();   map.unpause();  }  }
0 Kudos
1 Solution

Accepted Solutions
StephenQuan
Occasional Contributor
One way to mix MapView controls with LinearLayout is to put the LinearLayout inside a PopupWindow.

package com.esri.android.editdemo;  import com.esri.android.map.GraphicsLayer; import com.esri.android.map.MapView; import com.esri.android.map.ags.ArcGISTiledMapServiceLayer; import com.esri.android.map.event.OnSingleTapListener; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.GeometryEngine; import com.esri.core.geometry.Point; import com.esri.core.geometry.SpatialReference; import com.esri.core.map.Graphic; import com.esri.core.symbol.SimpleMarkerSymbol;  import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.Toast;  public class EditDemoActivity extends Activity {  MapView map = null;  GraphicsLayer graphicsLayer = null;  SpatialReference webMercator = SpatialReference.create(102100);  PopupWindow popupWindow = null;   public void onCreate(Bundle savedInstanceState)  {   super.onCreate(savedInstanceState);      map = new MapView(this);   setContentView(map);    // Add the ArcGIS Online layer to the map.   map.addLayer(new ArcGISTiledMapServiceLayer("" +   "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));   map.setOnSingleTapListener(new OnSingleTapListener()   {    public void onSingleTap(float x, float y)    {     Point newPoint = map.toMapPoint(new Point(x, y));     SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(Color.RED, 20, SimpleMarkerSymbol.STYLE.CIRCLE);     graphicsLayer.addGraphic(new Graphic(newPoint, simpleMarkerSymbol));    }   });      // Set the extent to ESRI Redlands Campus   Point minPoint = GeometryEngine.project(-117.200, 34.057, webMercator);   Point maxPoint = GeometryEngine.project(-117.198, 34.059, webMercator);   Envelope extent = new Envelope(minPoint.getX(), minPoint.getY(), maxPoint.getX(), maxPoint.getY());   extent.inflate(10000, 10000);   map.setExtent(extent);    // Create a graphics layer and add it to the map.   graphicsLayer = new GraphicsLayer();   map.addLayer(graphicsLayer);        // Post create PopupWindow since it created during onCreate().   final Context context = this;   map.post(    new Runnable()    {     public void run()     {      popupWindow = new PopupWindow(context);      LinearLayout linearLayout = new LinearLayout(context);      linearLayout.setOrientation(LinearLayout.HORIZONTAL);      Button button = new Button(context);      button.setText("Clear");      button.setOnClickListener(new OnClickListener()      {       public void onClick(View v)       {        graphicsLayer.removeAll();        Toast.makeText(context, "Graphics Layer Cleared", Toast.LENGTH_SHORT).show();       }      });      linearLayout.addView(button);      popupWindow.setContentView(linearLayout);      popupWindow.showAtLocation(linearLayout, Gravity.LEFT | Gravity.BOTTOM, 10, 10);      popupWindow.update(64, 64);     }    }   );  }    protected void onPause()  {   super.onPause();   map.pause();  }   protected void onResume()  {   super.onResume();   map.unpause();  } }

View solution in original post

0 Kudos
3 Replies
StephenQuan
Occasional Contributor
One way to mix MapView controls with LinearLayout is to put the LinearLayout inside a PopupWindow.

package com.esri.android.editdemo;  import com.esri.android.map.GraphicsLayer; import com.esri.android.map.MapView; import com.esri.android.map.ags.ArcGISTiledMapServiceLayer; import com.esri.android.map.event.OnSingleTapListener; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.GeometryEngine; import com.esri.core.geometry.Point; import com.esri.core.geometry.SpatialReference; import com.esri.core.map.Graphic; import com.esri.core.symbol.SimpleMarkerSymbol;  import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.Toast;  public class EditDemoActivity extends Activity {  MapView map = null;  GraphicsLayer graphicsLayer = null;  SpatialReference webMercator = SpatialReference.create(102100);  PopupWindow popupWindow = null;   public void onCreate(Bundle savedInstanceState)  {   super.onCreate(savedInstanceState);      map = new MapView(this);   setContentView(map);    // Add the ArcGIS Online layer to the map.   map.addLayer(new ArcGISTiledMapServiceLayer("" +   "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));   map.setOnSingleTapListener(new OnSingleTapListener()   {    public void onSingleTap(float x, float y)    {     Point newPoint = map.toMapPoint(new Point(x, y));     SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(Color.RED, 20, SimpleMarkerSymbol.STYLE.CIRCLE);     graphicsLayer.addGraphic(new Graphic(newPoint, simpleMarkerSymbol));    }   });      // Set the extent to ESRI Redlands Campus   Point minPoint = GeometryEngine.project(-117.200, 34.057, webMercator);   Point maxPoint = GeometryEngine.project(-117.198, 34.059, webMercator);   Envelope extent = new Envelope(minPoint.getX(), minPoint.getY(), maxPoint.getX(), maxPoint.getY());   extent.inflate(10000, 10000);   map.setExtent(extent);    // Create a graphics layer and add it to the map.   graphicsLayer = new GraphicsLayer();   map.addLayer(graphicsLayer);        // Post create PopupWindow since it created during onCreate().   final Context context = this;   map.post(    new Runnable()    {     public void run()     {      popupWindow = new PopupWindow(context);      LinearLayout linearLayout = new LinearLayout(context);      linearLayout.setOrientation(LinearLayout.HORIZONTAL);      Button button = new Button(context);      button.setText("Clear");      button.setOnClickListener(new OnClickListener()      {       public void onClick(View v)       {        graphicsLayer.removeAll();        Toast.makeText(context, "Graphics Layer Cleared", Toast.LENGTH_SHORT).show();       }      });      linearLayout.addView(button);      popupWindow.setContentView(linearLayout);      popupWindow.showAtLocation(linearLayout, Gravity.LEFT | Gravity.BOTTOM, 10, 10);      popupWindow.update(64, 64);     }    }   );  }    protected void onPause()  {   super.onPause();   map.pause();  }   protected void onResume()  {   super.onResume();   map.unpause();  } }
0 Kudos
JohnAllen
New Contributor III
stephen_quan,

I'm new to programming and Android. I'm not sure if this is what you're trying to do, but I'll explain what I did.

I was trying to add buttons to my mapview, then make the buttons do certain tasks.

I added all my buttons in my layout .xml and placed them in a scroll view and then I was unable to see my mapview, just my buttons. The mapview was black.

This was because I included the following code inside the <ScrollView> paramaters:

____________________________
<com.esri.android.map.MapView
  android:id="@+id/map"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  initExtent = "-7098834.76609481 3358609.41519039 -8699276.01384915 34022683.36288386">
  </com.esri.android.map.MapView>
____________________________


So I placed it outside the <ScrollView> and everything appeared. Pretty basic.

My final code looked like this in my layout xml file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >   
  <!-- MapView layout and initial extent -->
  <ScrollView
      android:layout_width="fill_parent"
      android:layout_height= "160dp">
     
    <LinearLayout
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">
 
    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Activate GPS" />

    <Button
        android:id="@+id/button2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="De-Activate GPS" />
   
    <Button
        android:id="@+id/button3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Zoom to my location" />
 
   </LinearLayout>
    </ScrollView>
   
    <com.esri.android.map.MapView
  android:id="@+id/map"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  initExtent = "-7098834.76609481 3358609.41519039 -8699276.01384915 34022683.36288386">
  </com.esri.android.map.MapView>
 
  </LinearLayout>
0 Kudos
JohnAllen
New Contributor III
Stephen,

Your second post on this thread helped me out a lot.

I was having trouble using the webmaps and my XML layout, one would cover the other.

So, I used the [ popupWindow ] to place a button on my webmap view.

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

import com.esri.android.map.Layer;
import com.esri.android.map.MapView;
import com.esri.android.map.PopupContainer;
import com.esri.android.map.PopupView;
import com.esri.android.map.ags.ArcGISDynamicMapServiceLayer;
import com.esri.android.map.ags.ArcGISFeatureLayer;
import com.esri.android.map.ags.ArcGISLayerInfo;
import com.esri.android.map.event.OnSingleTapListener;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.map.FeatureSet;
import com.esri.core.map.Graphic;
import com.esri.core.map.popup.PopupInfo;
import com.esri.core.tasks.ags.query.Query;
import com.esri.core.tasks.ags.query.QueryTask;

public class MapscreenMain extends Activity {
  private MapView map;
  private PopupContainer popupContainer;
  private PopupDialog popupDialog;
  private ProgressDialog progressDialog;
  private AtomicInteger count;
  PopupWindow popupWindow = null;
 
  /** Called when the activity is first created. */    
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // Load a webmap.
    map = new MapView(this, "http://www.arcgis.com/home/item.html?id=ec84873154cf4d7f07", "", "");
    setContentView(map);
    
 // Post create PopupWindow since it created during onCreate().
   final Context context = this;
   map.post(
    new Runnable()
    {
     public void run()
     {
      popupWindow = new PopupWindow(context);
      LinearLayout linearLayout = new LinearLayout(context);
      linearLayout.setOrientation(LinearLayout.HORIZONTAL);
      Button button = new Button(context);
      button.setText("Clear");
      linearLayout.addView(button);
      popupWindow.setContentView(linearLayout);
      popupWindow.showAtLocation(linearLayout, Gravity.LEFT | Gravity.BOTTOM, 10, 10);
      popupWindow.update(64, 64);
     }
    });
    
    // Tap on the map and show popups for selected features.
    map.setOnSingleTapListener(new OnSingleTapListener() {
      private static final long serialVersionUID = 1L;.....................ect.

      public void onSingleTap(float x, float y) {     


I haven't set the button to do anything yet, but I was happy to just add it to my map view.

Thanks,

P.S. My first post on this thread you can ignore. Don't think that was what you were looking for.
0 Kudos