Location pickers in apps are useful for helping people coordinate rides and deliveries while on the go. Here’s how to build one for your app using the Android SDK!

The main components needed to make a location picker are an Android ImageView for the drop pin, the Mapbox Android SDK Marker API, and Mapbox Android Services to do the geocoding. To get started add a Mapbox MapView to your app and display it across the width and height of the app.

Drop pin

The drop pin is the statically positioned image that is used to select a location on the map. While it stays centered on the map, the user can pinch and zoom the map to find their desired location. It’s built using an Android ImageView with a custom image.

// Create drop pin using custom image
ImageView dropPinView = new ImageView(this);
dropPinView.setImageResource(R.drawable.ic_droppin_24dp);

// Statically Set drop pin in center of screen
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
float density = getResources().getDisplayMetrics().density;
params.bottomMargin = (int) (12 * density);
dropPinView.setLayoutParams(params);
mapView.addView(dropPinView);

Mapbox Android Marker API

Once the user chooses the location, the UI responds by simultaneously hiding the drop pin and replacing it with a Mapbox Android Marker with an open InfoWindow. We’ll use the InfoWindow to let the user know that the geocoder is busy looking up the address and then replace the content with the found address when it’s done.

// Make drop pin invisible
dropPinView.setVisibility(View.INVISIBLE);

// Get LatLng of selected location
LatLng position = mapboxMap.getProjection().fromScreenLocation(new PointF(dropPinView.getLeft() + (dropPinView.getWidth() / 2), dropPinView.getBottom()));

// Remove previous address pin (if exists)
if (addressPin != null) {
    if (mapboxMap != null && addressPin != null) {
        mapboxMap.removeMarker(addressPin);
    }
}

//Create new address pin
addressPin = mapboxMap.addMarker(new MarkerViewOptions().title("Loading address...").position(position));
mapboxMap.selectMarker(addressPin);

// Start the Geocoding...

Mapbox Geocoding

Now that the UI is showing the selection the next step is to find the address using the Mapbox geocoder and then display it in the Address Pin’s InfoWindow.

//Create Geocoding client
MapboxGeocoding client = new MapboxGeocoding.Builder()
    .setAccessToken(getString(R.string.mapbox_access_token))
    .setCoordinates(Position.fromCoordinates(position.getLongitude(), position.getLatitude()))
    .setType(GeocodingCriteria.TYPE_ADDRESS)
    .build();

//Place the request
client.enqueueCall(new Callback<GeocodingResponse>() {
	@Override
    public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {

		List<GeocodingFeature> results = response.body().getFeatures();
    	String address = null;
        if (results.size() > 0) {
            GeocodingFeature feature = results.get(0);
            address = feature.getAddress() + " " + feature.getText();

            // Update Address Pin's InfoWindow With Address
            if (addressPin != null) {
            	addressPin.setTitle(TextUtils.isEmpty(address) ? "No address found" : address);
        	}
        }
    }

    @Override
    public void onFailure(Call<GeocodingResponse> call, Throwable t) {
        Log.e(TAG, "Geocoding Failure: " + t.getMessage());
    }
});

Putting it all together

By using a standard Android ImageView along with the Mapbox Android SDK, we’re able to quickly build a way for the app’s user to pick a location on the map. Here’s what it looks like in action:

More ideas

There are many more bells and whistles that you can use to customize the location picker in your app. To see a few that we’ve added, please check out the full working code example in the TestApp. If you have questions about how to build a location picker or want to share what you’re working on, hit me up on Twitter @bradleege.