MapView CameraPosition Method

This example shows CameraPosition Method on MapView

  • CameraPosition Method

    • target

    • zoom

    • bearing

    • tilt

MapView CameraPosition Method

For all code examples, refer to Android Maps SDK Code Examples

activity_camera_position.xml view source

1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:app="http://schemas.android.com/apk/res-auto"
4
android:id="@+id/coordinator_layout"
5
android:layout_width="match_parent"
6
android:layout_height="match_parent">
7
8
<ai.nextbillion.maps.core.MapView
9
android:id="@id/mapView"
10
android:layout_width="match_parent"
11
android:layout_height="match_parent"
12
app:nbmap_uiAttributionTintColor="@color/redAccent" />
13
14
<com.google.android.material.floatingactionbutton.FloatingActionButton
15
android:id="@+id/fab"
16
android:layout_width="wrap_content"
17
android:layout_height="wrap_content"
18
android:layout_gravity="end|bottom"
19
android:layout_margin="@dimen/fab_margin"
20
app:srcCompat="@drawable/ic_input"
21
app:backgroundTint="@android:color/white" />
22
23
</androidx.coordinatorlayout.widget.CoordinatorLayout>

CameraPositionActivity view source

1
package ai.nextbillion;
2
3
import android.content.Context;
4
import android.content.DialogInterface;
5
import android.os.Bundle;
6
import android.view.LayoutInflater;
7
import android.view.View;
8
import android.widget.SeekBar;
9
import android.widget.TextView;
10
import android.widget.Toast;
11
12
import com.google.android.material.floatingactionbutton.FloatingActionButton;
13
14
import ai.nextbillion.maps.camera.CameraPosition;
15
import ai.nextbillion.maps.camera.CameraUpdateFactory;
16
import ai.nextbillion.maps.core.MapView;
17
import ai.nextbillion.maps.core.NextbillionMap;
18
import ai.nextbillion.maps.core.OnMapReadyCallback;
19
import ai.nextbillion.maps.geometry.LatLng;
20
import androidx.annotation.IdRes;
21
import androidx.annotation.NonNull;
22
import androidx.appcompat.app.AlertDialog;
23
import androidx.appcompat.app.AppCompatActivity;
24
import androidx.core.content.ContextCompat;
25
26
import static ai.nextbillion.maps.constants.GeometryConstants.MAX_LATITUDE;
27
import static ai.nextbillion.maps.constants.GeometryConstants.MIN_LATITUDE;
28
29
/**
30
* Test activity showcasing how to listen to camera change events.
31
*/
32
public class CameraPositionActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener,
33
NextbillionMap.OnMapLongClickListener {
34
35
private MapView mapView;
36
private NextbillionMap nextbillionMap;
37
private FloatingActionButton fab;
38
private boolean logCameraChanges;
39
40
@Override
41
protected void onCreate(Bundle savedInstanceState) {
42
super.onCreate(savedInstanceState);
43
setContentView(R.layout.activity_camera_position);
44
mapView = findViewById(R.id.mapView);
45
mapView.onCreate(savedInstanceState);
46
mapView.getMapAsync(this);
47
}
48
49
@Override
50
public void onMapReady(@NonNull final NextbillionMap map) {
51
nextbillionMap = map;
52
map.setStyle(StyleConstants.LIGHT, style -> {
53
// add a listener to FAB
54
fab = findViewById(R.id.fab);
55
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.palette_mint_100));
56
fab.setOnClickListener(this);
57
58
toggleLogCameraChanges();
59
60
// listen to long click events to toggle logging camera changes
61
nextbillionMap.addOnMapLongClickListener(this);
62
});
63
}
64
65
@Override
66
public boolean onMapLongClick(@NonNull LatLng point) {
67
toggleLogCameraChanges();
68
return false;
69
}
70
71
@Override
72
public void onClick(View view) {
73
Context context = view.getContext();
74
final View dialogContent = LayoutInflater.from(context).inflate(R.layout.dialog_camera_position, null);
75
AlertDialog.Builder builder = new AlertDialog.Builder(context);
76
builder.setTitle(R.string.dialog_camera_position);
77
builder.setView(onInflateDialogContent(dialogContent));
78
builder.setPositiveButton("Animate", new DialogClickListener(nextbillionMap, dialogContent));
79
builder.setNegativeButton("Cancel", null);
80
builder.setCancelable(false);
81
builder.show();
82
}
83
84
private void toggleLogCameraChanges() {
85
logCameraChanges = !logCameraChanges;
86
if (logCameraChanges) {
87
nextbillionMap.addOnCameraIdleListener(idleListener);
88
nextbillionMap.addOnCameraMoveCancelListener(moveCanceledListener);
89
nextbillionMap.addOnCameraMoveListener(moveListener);
90
nextbillionMap.addOnCameraMoveStartedListener(moveStartedListener);
91
} else {
92
nextbillionMap.removeOnCameraIdleListener(idleListener);
93
nextbillionMap.removeOnCameraMoveCancelListener(moveCanceledListener);
94
nextbillionMap.removeOnCameraMoveListener(moveListener);
95
nextbillionMap.removeOnCameraMoveStartedListener(moveStartedListener);
96
}
97
}
98
99
@Override
100
protected void onStart() {
101
super.onStart();
102
mapView.onStart();
103
}
104
105
@Override
106
protected void onResume() {
107
super.onResume();
108
mapView.onResume();
109
}
110
111
@Override
112
protected void onPause() {
113
super.onPause();
114
mapView.onPause();
115
}
116
117
@Override
118
protected void onStop() {
119
super.onStop();
120
mapView.onStop();
121
}
122
123
@Override
124
protected void onDestroy() {
125
super.onDestroy();
126
if (nextbillionMap != null) {
127
nextbillionMap.removeOnMapLongClickListener(this);
128
}
129
mapView.onDestroy();
130
}
131
132
@Override
133
protected void onSaveInstanceState(Bundle outState) {
134
super.onSaveInstanceState(outState);
135
mapView.onSaveInstanceState(outState);
136
}
137
138
private View onInflateDialogContent(View view) {
139
linkTextView(view, R.id.value_lat, R.id.seekbar_lat, new LatLngChangeListener(), 180 + 38);
140
linkTextView(view, R.id.value_lon, R.id.seekbar_lon, new LatLngChangeListener(), 180 - 77);
141
linkTextView(view, R.id.value_zoom, R.id.seekbar_zoom, new ValueChangeListener(), 6);
142
linkTextView(view, R.id.value_bearing, R.id.seekbar_bearing, new ValueChangeListener(), 90);
143
linkTextView(view, R.id.value_tilt, R.id.seekbar_tilt, new ValueChangeListener(), 40);
144
return view;
145
}
146
147
private void linkTextView(
148
View view, @IdRes int textViewRes, @IdRes int seekBarRes, ValueChangeListener listener, int defaultValue) {
149
final TextView value = (TextView) view.findViewById(textViewRes);
150
SeekBar seekBar = (SeekBar) view.findViewById(seekBarRes);
151
listener.setLinkedValueView(value);
152
seekBar.setOnSeekBarChangeListener(listener);
153
seekBar.setProgress(defaultValue);
154
}
155
156
private NextbillionMap.OnCameraIdleListener idleListener = new NextbillionMap.OnCameraIdleListener() {
157
@Override
158
public void onCameraIdle() {
159
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_green_dark));
160
}
161
};
162
163
private NextbillionMap.OnCameraMoveListener moveListener = new NextbillionMap.OnCameraMoveListener() {
164
@Override
165
public void onCameraMove() {
166
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_orange_dark));
167
}
168
};
169
170
private NextbillionMap.OnCameraMoveCanceledListener moveCanceledListener = () -> {};
171
172
private NextbillionMap.OnCameraMoveStartedListener moveStartedListener = new NextbillionMap.OnCameraMoveStartedListener() {
173
174
private final String[] REASONS = {"REASON_API_GESTURE", "REASON_DEVELOPER_ANIMATION", "REASON_API_ANIMATION"};
175
176
@Override
177
public void onCameraMoveStarted(int reason) {
178
// reason ranges from 1 <-> 3
179
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_red_dark));
180
}
181
};
182
183
private class ValueChangeListener implements SeekBar.OnSeekBarChangeListener {
184
185
protected TextView textView;
186
187
public void setLinkedValueView(TextView textView) {
188
this.textView = textView;
189
}
190
191
@Override
192
public void onStartTrackingTouch(SeekBar seekBar) {
193
194
}
195
196
@Override
197
public void onStopTrackingTouch(SeekBar seekBar) {
198
199
}
200
201
@Override
202
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
203
textView.setText(String.valueOf(progress));
204
}
205
}
206
207
private class LatLngChangeListener extends ValueChangeListener {
208
209
@Override
210
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
211
super.onProgressChanged(seekBar, progress - 180, fromUser);
212
}
213
}
214
215
private static class DialogClickListener implements DialogInterface.OnClickListener {
216
217
private NextbillionMap nextbillionMap;
218
private View dialogContent;
219
220
public DialogClickListener(NextbillionMap nextbillionMap, View view) {
221
this.nextbillionMap = nextbillionMap;
222
this.dialogContent = view;
223
}
224
225
@Override
226
public void onClick(DialogInterface dialog, int which) {
227
double latitude = Double.parseDouble(
228
((TextView) dialogContent.findViewById(R.id.value_lat)).getText().toString());
229
double longitude = Double.parseDouble(
230
((TextView) dialogContent.findViewById(R.id.value_lon)).getText().toString());
231
double zoom = Double.parseDouble(
232
((TextView) dialogContent.findViewById(R.id.value_zoom)).getText().toString());
233
double bearing = Double.parseDouble(
234
((TextView) dialogContent.findViewById(R.id.value_bearing)).getText().toString());
235
double tilt = Double.parseDouble(
236
((TextView) dialogContent.findViewById(R.id.value_tilt)).getText().toString());
237
238
if (latitude < MIN_LATITUDE || latitude > MAX_LATITUDE) {
239
Toast.makeText(dialogContent.getContext(), "latitude value must be set "
240
+ " between " + MIN_LATITUDE + " and " + MAX_LATITUDE,
241
Toast.LENGTH_SHORT).show();
242
return;
243
}
244
245
CameraPosition cameraPosition = new CameraPosition.Builder()
246
.target(new LatLng(latitude, longitude))
247
.zoom(zoom)
248
.bearing(bearing)
249
.tilt(tilt)
250
.build();
251
252
nextbillionMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000,
253
new NextbillionMap.CancelableCallback() {
254
@Override
255
public void onCancel() {
256
}
257
258
@Override
259
public void onFinish() {
260
}
261
});
262
}
263
}
264
}

The code is an activity called CameraPositionActivity that demonstrates how to listen to camera change events in a map view. It uses the Nextbillion Maps SDK for Android.

initMapView:

  • The map view is initialized in the onCreate method by setting the content view to the layout file activity_camera_position.xml. The map view is found using findViewById and the getMapAsync method is called to set the callback for when the map is ready.

Operations on Camera Position:

  • The onMapReady method is implemented to receive the NextbillionMap object when it is ready. The map style is set to StyleConstants.SATELLITE_STREETS, and a listener is added to a floating action button (FAB).

  • The toggleLogCameraChanges method is used to toggle the logging of camera changes. When logging is enabled, listeners for camera events are added to the map. When logging is disabled, the listeners are removed.

  • The onMapLongClick method is implemented to toggle the logging of camera changes when a long click event occurs on the map.

  • The onClick method is implemented to show a dialog when the FAB is clicked. The dialog allows the user to set the camera position parameters (latitude, longitude, zoom, bearing, and tilt) and animates the camera to the new position when the "Animate" button is clicked.

  • The LatLngChangeListener class extends ValueChangeListener and adjusts the latitude value by subtracting 180, as the seek bar range is from 0 to 360 but latitude ranges from -90 to 90.

  • The DialogClickListener class is an implementation of DialogInterface.OnClickListener that retrieves the camera position parameters from the dialog content and animates the camera to the new position using nextbillionMap.animateCamera.

Additionally, the code includes lifecycle methods (onStart, onResume, onPause, onStop, onDestroy, onSaveInstanceState) to manage the state of the map view and release resources properly.

The activity demonstrates how to initialize a map view, handle camera change events, and interact with the camera position using a dialog.

© 2024 NextBillion.ai all rights reserved.