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;
12
import com.google.android.material.floatingactionbutton.FloatingActionButton;
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;
26
import static ai.nextbillion.maps.constants.GeometryConstants.MAX_LATITUDE;
27
import static ai.nextbillion.maps.constants.GeometryConstants.MIN_LATITUDE;
30
* Test activity showcasing how to listen to camera change events.
32
public class CameraPositionActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener,
33
NextbillionMap.OnMapLongClickListener {
35
private MapView mapView;
36
private NextbillionMap nextbillionMap;
37
private FloatingActionButton fab;
38
private boolean logCameraChanges;
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);
50
public void onMapReady(@NonNull final 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);
58
toggleLogCameraChanges();
60
// listen to long click events to toggle logging camera changes
61
nextbillionMap.addOnMapLongClickListener(this);
66
public boolean onMapLongClick(@NonNull LatLng point) {
67
toggleLogCameraChanges();
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);
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);
92
nextbillionMap.removeOnCameraIdleListener(idleListener);
93
nextbillionMap.removeOnCameraMoveCancelListener(moveCanceledListener);
94
nextbillionMap.removeOnCameraMoveListener(moveListener);
95
nextbillionMap.removeOnCameraMoveStartedListener(moveStartedListener);
100
protected void onStart() {
106
protected void onResume() {
112
protected void onPause() {
118
protected void onStop() {
124
protected void onDestroy() {
126
if (nextbillionMap != null) {
127
nextbillionMap.removeOnMapLongClickListener(this);
133
protected void onSaveInstanceState(Bundle outState) {
134
super.onSaveInstanceState(outState);
135
mapView.onSaveInstanceState(outState);
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);
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);
156
private NextbillionMap.OnCameraIdleListener idleListener = new NextbillionMap.OnCameraIdleListener() {
158
public void onCameraIdle() {
159
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_green_dark));
163
private NextbillionMap.OnCameraMoveListener moveListener = new NextbillionMap.OnCameraMoveListener() {
165
public void onCameraMove() {
166
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_orange_dark));
170
private NextbillionMap.OnCameraMoveCanceledListener moveCanceledListener = () -> {};
172
private NextbillionMap.OnCameraMoveStartedListener moveStartedListener = new NextbillionMap.OnCameraMoveStartedListener() {
174
private final String[] REASONS = {"REASON_API_GESTURE", "REASON_DEVELOPER_ANIMATION", "REASON_API_ANIMATION"};
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));
183
private class ValueChangeListener implements SeekBar.OnSeekBarChangeListener {
185
protected TextView textView;
187
public void setLinkedValueView(TextView textView) {
188
this.textView = textView;
192
public void onStartTrackingTouch(SeekBar seekBar) {
197
public void onStopTrackingTouch(SeekBar seekBar) {
202
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
203
textView.setText(String.valueOf(progress));
207
private class LatLngChangeListener extends ValueChangeListener {
210
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
211
super.onProgressChanged(seekBar, progress - 180, fromUser);
215
private static class DialogClickListener implements DialogInterface.OnClickListener {
217
private NextbillionMap nextbillionMap;
218
private View dialogContent;
220
public DialogClickListener(NextbillionMap nextbillionMap, View view) {
221
this.nextbillionMap = nextbillionMap;
222
this.dialogContent = view;
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());
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();
245
CameraPosition cameraPosition = new CameraPosition.Builder()
246
.target(new LatLng(latitude, longitude))
252
nextbillionMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000,
253
new NextbillionMap.CancelableCallback() {
255
public void onCancel() {
259
public void onFinish() {