Loading...
Searching...
No Matches
DefaultNavigationView.java
Go to the documentation of this file.
1package com.navigine.view;
2
3import android.content.Context;
4import android.graphics.Color;
5import android.graphics.PointF;
6import android.util.AttributeSet;
7import android.view.Gravity;
8import android.view.ViewGroup;
9import android.widget.FrameLayout;
10
11import com.navigine.idl.java.Building;
12import com.navigine.idl.java.BuildingListener;
13import com.navigine.idl.java.CameraListener;
14import com.navigine.idl.java.CameraUpdateReason;
15import com.navigine.idl.java.NavigineSdk;
16import com.navigine.idl.java.Sublocation;
17import com.navigine.idl.java.SublocationChangeListener;
18import com.navigine.view.widgets.FloorSelectorView;
19import com.navigine.view.widgets.FloorSelectorViewConfig;
20import com.navigine.view.widgets.FollowMeButton;
21import com.navigine.view.widgets.FollowMeButtonConfig;
22import com.navigine.view.widgets.ZoomControls;
23import com.navigine.view.widgets.ZoomControlsConfig;
24import com.navigine.idl.java.UserLocationLayer;
25
26import java.util.ArrayList;
27import java.util.List;
28
75public class DefaultNavigationView extends LocationView {
76 public static final String TAG = DefaultNavigationView.class.getCanonicalName();
77
78 private DefaultNavigationViewConfig viewConfig;
79 private ZoomControlsConfig zoomControlsConfig;
80 private FollowMeButtonConfig followMeButtonConfig;
81 private FloorSelectorViewConfig floorSelectorConfig;
82
92 public DefaultNavigationView(final Context context) {
93 this(context, null, null, null, null, null);
94 }
95
97 public DefaultNavigationView(final Context context, final AttributeSet attrs) {
98 this(context, attrs, null, null, null, null);
99 }
100
110 public DefaultNavigationView(final Context context, final AttributeSet attrs,
111 final DefaultNavigationViewConfig viewConfig) {
112 this(context, attrs, viewConfig, null, null, null);
113 }
114
119 public DefaultNavigationView(final Context context, final AttributeSet attrs,
120 final DefaultNavigationViewConfig viewConfig,
121 final ZoomControlsConfig zoomConfig,
122 final FollowMeButtonConfig followMeConfig,
123 final FloorSelectorViewConfig floorConfig) {
124 super(context, attrs);
125 this.viewConfig = viewConfig != null ? viewConfig : DefaultNavigationViewConfig.defaultConfig();
126 this.zoomControlsConfig = zoomConfig != null ? zoomConfig : ZoomControlsConfig.defaultConfig();
127 this.followMeButtonConfig = followMeConfig != null ? followMeConfig : FollowMeButtonConfig.defaultConfig();
128 this.floorSelectorConfig = floorConfig != null ? floorConfig : FloorSelectorViewConfig.defaultConfig();
129 setupUI();
130 }
131
132 @Override
133 protected void onDetachedFromWindow() {
134 locationWindow.removeBuildingListener(buildingListener);
135 locationWindow.removeSublocationChangeListener(sublocationChangeListener);
136 locationWindow.removeCameraListener(cameraListener);
137 super.onDetachedFromWindow();
138 }
139
141 private void setupUI() {
142 sublocationChangeListener = new SublocationChangeListener() {
143 @Override
144 public void onActiveSublocationChanged(int sublocationId) {
145 if (floorSelector != null) {
146 floorSelector.setSublocationId(sublocationId);
147 }
148 }
149 };
150 locationWindow.addSublocationChangeListener(sublocationChangeListener);
151
152 zoomControls = new ZoomControls(getContext(),
153 this::zoomInPressed,
154 this::zoomOutPressed,
155 zoomControlsConfig);
156 FrameLayout.LayoutParams zoomLp = new FrameLayout.LayoutParams(
157 ViewGroup.LayoutParams.WRAP_CONTENT,
158 ViewGroup.LayoutParams.WRAP_CONTENT
159 );
160 zoomLp.gravity = Gravity.END | Gravity.CENTER_VERTICAL;
161 addView(zoomControls, zoomLp);
162
163 followMeButton = new FollowMeButton(getContext(),
164 this::followMePressed,
165 followMeButtonConfig);
166 FrameLayout.LayoutParams followLp = new FrameLayout.LayoutParams(
167 ViewGroup.LayoutParams.WRAP_CONTENT,
168 ViewGroup.LayoutParams.WRAP_CONTENT
169 );
170 followLp.gravity = Gravity.END | Gravity.BOTTOM;
171 addView(followMeButton, followLp);
172
173 floorSelector = new FloorSelectorView(getContext(),
174 (sublocationId) -> locationWindow.setSublocationId(sublocationId),
175 floorSelectorConfig);
176
177 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
178 ViewGroup.LayoutParams.WRAP_CONTENT,
179 ViewGroup.LayoutParams.WRAP_CONTENT
180 );
181 lp.gravity = Gravity.START | Gravity.TOP;
182 floorSelector.setVisibility(GONE);
183
184 addView(floorSelector, lp);
185
186 applyWidgetLayoutParams();
187 applyConfigVisibility();
188
189 buildingListener = new BuildingListener() {
190 @Override
191 public void onActiveBuildingFocused(Building activeBuilding) {
192 if (floorSelector == null || activeBuilding == null) {
193 return;
194 }
195 hideFloorSelectorOutsideBuildingFocus = false;
196 List<FloorSelectorView.LevelInfo> floors = new ArrayList<>();
197 for (Sublocation sublocation : activeBuilding.getSublocations()) {
198 if (sublocation == null) {
199 continue;
200 }
201 floors.add(new FloorSelectorView.LevelInfo(sublocation.getLevelId(), sublocation.getId()));
202 }
203 floorSelector.setFloors(floors);
204 floorSelector.setSublocationId(activeBuilding.getActiveSublocationId());
205 applyConfigVisibility();
206 }
207
208 @Override
209 public void onActiveBuildingLeft() {
210 if (floorSelector == null) {
211 return;
212 }
213 hideFloorSelectorOutsideBuildingFocus = true;
214 floorSelector.setFloors(new ArrayList<>());
215 floorSelector.setVisibility(GONE);
216 applyConfigVisibility();
217 }
218
219 @Override
220 public void onActiveSublocationChanged(int activeSublocationId) {
221 }
222 };
223 locationWindow.addBuildingListener(buildingListener);
224
225 userLocationLayer = NavigineSdk.getInstance().getUserLocationLayer(locationWindow);
226 userLocationLayer.setVisible(true);
227
228 cameraListener = new CameraListener() {
229 @Override
230 public void onCameraPositionChanged(CameraUpdateReason reason, boolean finished) {
231 if (reason == CameraUpdateReason.APPLICATION) {
232 return;
233 }
234
235 if (followMeButton != null && followMeButton.isFollowing()) {
236 userLocationLayer.resetAnchor();
237 followMeButton.updateAppearanceForFollowingState(false);
238 }
239 }
240 };
241 locationWindow.addCameraListener(cameraListener);
242 }
243
244
246 private void zoomInPressed() {
247 float currentZoom = locationWindow.getZoomFactor();
248 locationWindow.setZoomFactor(currentZoom * (3.f / 2.f));
249 }
250
252 private void zoomOutPressed() {
253 float currentZoom = locationWindow.getZoomFactor();
254 locationWindow.setZoomFactor(currentZoom * (2.f / 3.f));
255 }
256
257 private void applyConfigVisibility() {
258 if (zoomControls != null) {
259 zoomControls.setVisibility((viewConfig.getVisibleWidgets() & DefaultNavigationViewConfig.WIDGET_ZOOM_CONTROLS) != 0 ? VISIBLE : GONE);
260 }
261 if (followMeButton != null) {
262 followMeButton.setVisibility((viewConfig.getVisibleWidgets() & DefaultNavigationViewConfig.WIDGET_FOLLOW_ME) != 0 ? VISIBLE : GONE);
263 }
264 if (floorSelector != null) {
265 boolean floorVisible = (viewConfig.getVisibleWidgets() & DefaultNavigationViewConfig.WIDGET_FLOOR_SELECTOR) != 0
266 && !hideFloorSelectorOutsideBuildingFocus
267 && floorSelector.getFloorsCount() > 1;
268 floorSelector.setVisibility(floorVisible ? VISIBLE : GONE);
269 }
270 }
271
272 private int dpToPx(int dp) {
273 return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
274 }
275
277 private void applyWidgetLayoutParams() {
278 if (zoomControls != null) {
279 FrameLayout.LayoutParams zoomLp = (FrameLayout.LayoutParams) zoomControls.getLayoutParams();
280 if (zoomLp == null) {
281 zoomLp = new FrameLayout.LayoutParams(
282 ViewGroup.LayoutParams.WRAP_CONTENT,
283 ViewGroup.LayoutParams.WRAP_CONTENT);
284 }
285 zoomLp.gravity = Gravity.END | Gravity.CENTER_VERTICAL;
286 ZoomControlsConfig zc = zoomControlsConfig;
287 int zoomRight = zc.getMarginRight() > 0
288 ? dpToPx(zc.getMarginRight())
289 : dpToPx((int) com.navigine.view.widgets.WidgetStyles.STANDARD_RIGHT_PADDING);
290 zoomLp.setMargins(0, 0, zoomRight, 0);
291 zoomControls.setLayoutParams(zoomLp);
292 int mv = zc.getMarginVertical();
293 zoomControls.setTranslationY(mv != 0 ? dpToPx(mv) / 2f : 0f);
294 }
295 if (followMeButton != null) {
296 FrameLayout.LayoutParams followLp = (FrameLayout.LayoutParams) followMeButton.getLayoutParams();
297 if (followLp == null) {
298 followLp = new FrameLayout.LayoutParams(
299 ViewGroup.LayoutParams.WRAP_CONTENT,
300 ViewGroup.LayoutParams.WRAP_CONTENT);
301 }
302 followLp.gravity = Gravity.END | Gravity.BOTTOM;
303 FollowMeButtonConfig fmConfig = followMeButtonConfig;
304 int rightPad = fmConfig.getMarginRight() > 0
305 ? dpToPx(fmConfig.getMarginRight())
306 : dpToPx((int) com.navigine.view.widgets.WidgetStyles.STANDARD_RIGHT_PADDING);
307 int bottomPad = fmConfig.getMarginBottom() > 0
308 ? dpToPx(fmConfig.getMarginBottom())
309 : dpToPx((int) com.navigine.view.widgets.WidgetStyles.FOLLOW_ME_BOTTOM_PADDING);
310 followLp.setMargins(0, 0, rightPad, bottomPad);
311 followMeButton.setLayoutParams(followLp);
312 }
313 if (floorSelector != null) {
314 FrameLayout.LayoutParams fl = (FrameLayout.LayoutParams) floorSelector.getLayoutParams();
315 if (fl == null) {
316 fl = new FrameLayout.LayoutParams(
317 ViewGroup.LayoutParams.WRAP_CONTENT,
318 ViewGroup.LayoutParams.WRAP_CONTENT);
319 }
320 fl.gravity = Gravity.START | Gravity.TOP;
321 FloorSelectorViewConfig fsConfig = floorSelectorConfig;
322 int leftPad = fsConfig.getMarginLeft() > 0
323 ? dpToPx(fsConfig.getMarginLeft())
324 : dpToPx((int) com.navigine.view.widgets.WidgetStyles.STANDARD_LEFT_PADDING);
325 int topPad = fsConfig.getMarginTop() > 0
326 ? dpToPx(fsConfig.getMarginTop())
327 : dpToPx((int) com.navigine.view.widgets.WidgetStyles.FLOOR_SELECTOR_TOP_PADDING);
328 fl.setMargins(leftPad, topPad, 0, 0);
329 floorSelector.setLayoutParams(fl);
330 }
331 }
332
337 private void followMePressed(boolean isFollowing) {
338 if (isFollowing) {
339 float centerX = getWidth() / 2f;
340 float centerY = getHeight() / 2f;
341 PointF anchorPoint = new PointF(centerX, centerY);
342 userLocationLayer.setAnchor(anchorPoint);
343 } else {
344 userLocationLayer.resetAnchor();
345 }
346 }
347
351 public void setViewConfig(DefaultNavigationViewConfig newViewConfig) {
352 if (newViewConfig != null) viewConfig = newViewConfig;
353 applyConfigVisibility();
354 }
355
367 public void setConfig(DefaultNavigationViewConfig newViewConfig,
368 ZoomControlsConfig newZoomConfig,
369 FollowMeButtonConfig newFollowMeConfig,
370 FloorSelectorViewConfig newFloorConfig) {
371 if (newViewConfig != null) viewConfig = newViewConfig;
372 if (newZoomConfig != null) zoomControlsConfig = newZoomConfig;
373 if (newFollowMeConfig != null) followMeButtonConfig = newFollowMeConfig;
374 if (newFloorConfig != null) floorSelectorConfig = newFloorConfig;
375 applyConfigVisibility();
376 if (zoomControls != null) zoomControls.applyConfig(zoomControlsConfig);
377 if (floorSelector != null) floorSelector.applyConfig(floorSelectorConfig);
378 if (followMeButton != null) followMeButton.applyConfig(followMeButtonConfig);
379 applyWidgetLayoutParams();
380 }
381
383 public DefaultNavigationViewConfig getViewConfig() { return viewConfig; }
385 public ZoomControlsConfig getZoomControlsConfig() { return zoomControlsConfig; }
387 public FollowMeButtonConfig getFollowMeButtonConfig() { return followMeButtonConfig; }
389 public FloorSelectorViewConfig getFloorSelectorConfig() { return floorSelectorConfig; }
390
401 public FloorSelectorView getFloorSelectorView() { return floorSelector; }
403 public ZoomControls getZoomControls() { return zoomControls; }
405 public FollowMeButton getFollowMeButton() { return followMeButton; }
406
408 private boolean hideFloorSelectorOutsideBuildingFocus = true;
409
410 private FloorSelectorView floorSelector;
411 private ZoomControls zoomControls;
412 private BuildingListener buildingListener;
413 private SublocationChangeListener sublocationChangeListener;
414 private UserLocationLayer userLocationLayer;
415 private CameraListener cameraListener;
416 private FollowMeButton followMeButton;
417}