Displaying Web Map Popups
A map is more than a picture. It conveys information about our surroundings and helps make decisions. But a picture does not tell the whole story. There is a wealth of information hidden behind the image. Popups are a great way to reveal information about features on a map, such as a business, a location, a natural phenomena, or a geopolitical entity.
You can configure popups when authoring web maps at ArcGIS Online. A popup is associated with a specific layer in a web map and describes how information about features in that layer should be presented. When configuring popups, the author of a web map can choose which fields to display, give them aliases, specify formatting for numbers and dates, configure charts, so on and so forth.
Learn more about authoring web maps with popups
Support Library
Developing with the Popup API uses Android API's that are not available on all supported platforms. If you are supporting Gingerbread and/or Honeycomb platforms then you need the Android support library added to your app. The support package includes support libraries that enable your app to take advantage of the newer API's.
Setting up your project to use the Android support library
To add the Android support library to your ArcGIS Android project:
- Right click your ArcGIS Android project and select Android Tools > Add Support Library
- Accept packages to install and click Install
- Under Android Dependencies you should see the android-support-v4.jar file library
- Ensure the support library is added to your project build path. Right click Android Dependencies in your project and select Build > Add to Build Path
Displaying information using popups
PopupContainer is the main class developers need to use to display popups in their applications. It provides the basic user interface (UI) and behavior for displaying and editing information about graphics in a popup. It holds and manages one or more Popup objects to provide a user infterface for attribute editing, media displaying, attachment managing, etc. It also manages the transitions between Popups.
- Instantiate a PopupContainer.
- Add Popups to the PopupContainer.
- Display the PopupContainer.
1. Instantiating PopupContainer
To instantiate PopupContainer, you need to pass a MapView as a parameter in the constructor.
MapView map = …;
PopupContainer popupContainer = new PopupContainer(map);
2. Adding a Popup to the PopupContainer
Popup is the class representation of a web map popup which associates a graphic with popup definition for the purpose of displaying in a PopupContainer. It manages a number of views behind the scenes, each of which is designed for a specific purpose, such as editing an attribute, displaying media, managing attachments, etc.
Each Popup contains a graphic whose information you want to display. The graphic could be chosen by a user in a variety of ways - by tapping on the map, or by tapping on the accessory button in the callout for a specific graphic. A popup definition is represented by a PopupInfo object. You can retrieve it from a layer of a web map.
Creating popup from a web map layer
You can create a popup from a layer of a web map provided you know which layer or service the popup is associated with.
MapView map = …;
Layer layer = …;
int subLayerId = …;
Graphic graphic = …;
……
Popup popup = layer.createPopup(map, subLayerId, graphic);
Feature layers are a special type of GraphicsLayer which allows you to display features from a layer from a map service or feature service. The ArcGISFeatureLayer class can create popup as shown below:
MapView map = …;
ArcGISFeatureLayer featureLayer = …;
Graphic graphic = …;
……
Popup popup = featureLayer.createPopup(map, 0, graphic);
Adding Popups to the PopupContainer
You can add a Popup to the PopupContainer by passing the reference to a graphic and the popup definition for that graphic.
Popup popup = …; // create popup
PopupContainer popupContainer = …;
popupContainer.addPopup(popup); // add popup to popup container
3. Displaying PopupContainer using PopupContainerView
PopupContainerView is a subclass of LinearLayout. Like any Android LinearLayout, it can be displayed in a variety of ways. The following is example of displaying a PopupContainerView.
// Create a dialog for the popups and display it.
PopupDialog popupDialog = new PopupDialog(map.getContext(), popupContainer);
...
// A customize full screen dialog.
private class PopupDialog extends Dialog {
private PopupContainer popupContainer;
public PopupDialog(Context context, PopupContainer popupContainer) {
super(context, android.R.style.Theme);
this.popupContainer = popupContainer;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LinearLayout layout = new LinearLayout(getContext());
layout.addView(popupContainer.getPopupContainerView(), android.widget.LinearLayout.LayoutParams.FILL_PARENT, android.widget.LinearLayout.LayoutParams.FILL_PARENT);
setContentView(layout, params);
}
}
Display popup for a hosted tiled map service
Popup can be configured on hosted tiled map services when published in conjunction with feature services. Hosted tiled map services don't have any attribute data. The feature service can be referenced to enable popup configuration options, and for displaying attribute information in maps. Showing popups defined for a hosted tiled map service follows the same steps mentioned in above sections. Popup can be created from the tiled map service layer. However, getting graphics relies on the associated feature service. The feature service referenced by a hosted tiled map service is exposed in API through method Layer.getQueryUrl(). You can create Popup for a hosted tiled map service as so
MapView map = …;
ArcGISTiledMapServiceLayer tiledLayer = …;
ArcGISLayerInfo layerInfo = …;
Envelope env = …;
Popup popup;
int layerID = layerInfo.getId();
String layerUrl = tiledLayer.getQueryUrl(layerID);
if (layerUrl == null)
layerUrl = tiledLayer.getUrl() + "/" + layerID;
ArcGISPopupInfo popupInfo = tiledLayer.getPopupInfo(layerID);
Query query = new Query();
query.setInSpatialReference(sr);
query.setOutSpatialReference(sr);
query.setGeometry(env);
query.setOutFields(new String[] {"*"});
QueryTask queryTask = new QueryTask(layerUrl);
try {
FeatureSet results = queryTask.execute(query);
for (Graphic graphic : results.getGraphics()) {
popup = tiledLayer.createPopup(map, layerID, graphic);
popupContainer.addPopup(popup);
}
} catch (Exception e) {
e.printStackTrace();
}
See Hosted tiled map services to learn more about this type of service.
Handling user interaction
The Popup class handles most of user interaction with the UI, such as bringing up an appropriate keyboard when the user starts editing a numeric attribute, allowing the user to take a picture or browse the photo gallery for attachments, etc.
To enable editing on a popup you call setEditMode(true)
// Add Popup
Popup popup = featureLayer.createPopup(map, 0, graphic);
popup.setEditMode(true);
popupContainer.addPopup(popup);
Editing information using popups
The popup API provides a UI that makes it very easy to collect information about a graphic from the user. It is your responsibility to commit the edits of a graphic to the server and present an appropriate view which will allow the user to edit an existing graphic's geometry, or create a new geometry from scratch. The Popup class provides a method to retrieve the edited attributes. And a PopupListener will be triggered by some changes of the state of the popup. The following are two examples of getting updated attributes and handling changes of the state of popup through PopupListener.
Retrieving updated attributes from popup
Popup popup = …;
Graphic gr = popup.getGraphic();
Map<String, Object> attributes = gr.getAttributes();
Map<String, Object> updatedAttrs = popup.getUpdatedAttributes();
for (Entry<String, Object> entry : updatedAttrs.entrySet()) {
attributes.put(entry.getKey(), entry.getValue());
}
Graphic newgr = new Graphic(gr.getGeometry(), null, attributes, null);
Listen to changes of popup state
Popup popup = …;
popup.setPopupListener(this);
popup.setEditMode(true);
……
@Override
public void onPopupModified() {
Log.i(IOUtils.TAG, "onPopupModified");
mModified = true;
View titleView = getPopup().getLayout().getTitleView();
if (titleView != null && titleView instanceof ArcGISTitleView) {
Symbol symbol = ((ArcGISTitleView) titleView).getSymbol();
if (symbol != null && symbol != mSymbol) {
Log.i(IOUtils.TAG, "onPopupModified: update symbol");
mSymbol = symbol;
addFeature(mCurrentLocation);
}
}
……;
}
@Override
public void onPopupValidityChanged(boolean isValid) {
Log.i(IOUtils.TAG, "onPopupValidityChanged");
mModified = true;
mValid = isValid;
}
Editor tracking and ownership-based access control
Editor tracking and ownership-based access control are two features that are only available with feature services hosted on ArcGIS Online or on ArcGIS Server 10.1 and above. These two features affect the display and behaviors of popups.
Editor tracking
When edit tracking is enabled, a feature layer automatically tracks and manages information such as as 1) The user who created or modified a feature and 2) The time when the feature was created or modified. This tracking information is stored along with the feature in specially designated fields. The information about these designated fields are exposed in the API through method ArcGISFeatureLayer.getEditFieldsInfo() . Popup automatically prevents a user from modifying these fields. Popup also shows a localized summary of the last edit operation performed on the given feature above the title of the popup. The The API exposes the edit information through method ArcGISFeatureLayer.getEditInfo() .
Popup uses template to display the edit summary. The templates are stored in a xml file called arcgis_ui_strings.xml. And they can be customized. Read “Customizing the UI” for more information about how to customize those templates.
Ownership-based access control
Ownership-based access control configuration specifies whether features can be edited only by their owners, or if they can be edited by anyone; even if they belong to someone else. The configuration of a feature layer is exposed in the API through methods such as ArcGISFeatureLayer.getOwnershipBasedAccessControlForFeatures(). Popup enforce this configuration to prevent an unauthorized user from making edits to a feature. The buttons in a popup such as Edit button, Delete button and Save Button will be turned on/off according to the configuration. Popup API also exposes the configuration for a specific feature through methods Popup.isDeletable() and isEditable().
Customizing the UI
Color
You can change the color of popup background, text and selector by modifying some property on PopupContainer.
PopupContainer popupContainer = …;
popupContainer.setPopupBackgroundColor(Color.WHITE); // popup background color
popupContainer.setPopupTextColor(Color.BLACK); // text color
popupContainer.setPopupSelectorColors(Color.BLUE, Color.RED,
Color.CYAN, Color.MAGENTA); // selector colors
Custom Action
You can replace default toolbar of the popup view by setting the PopupToolbar property on PopupContainer. You can perform any action when the buttons in the custom toolbar are clicked, such as zooming into the feature being displayed in the popup, or displaying a custom action sheet with further options.
Localizing the UI
The text displayed in the popup views has been externalized into a xml file called arcgis_ui_strings.xml to make localization easy. This file is included in the res/values folder for each local. Translations for the following languages are included by default-
- Arabic
- German
- English
- Spanish
- French
- Italian
- Japanese
- Korean
- Portuguese
- Russian
- Chinese
When displaying the UI, the PopupContainer will automatically pick up the appropriate translations from resources folder depending upon the language setting of the device.