diff options
author | Tobrun <tobrun.van.nuland@gmail.com> | 2019-06-24 09:08:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-24 09:08:26 +0200 |
commit | e60b48eca9e752a09e54d4b1277ac1ab6aec5629 (patch) | |
tree | 6b452cd90e2257eaeca97ea1f6140b3784a669cb /platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk | |
parent | f7f74a6deb57ad4ac22a30604a0dce39024feca2 (diff) | |
download | qtlocation-mapboxgl-e60b48eca9e752a09e54d4b1277ac1ab6aec5629.tar.gz |
[android] - update LatLngBounds example with animating bottomsheet scroll behavior (#14924)
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk')
2 files changed, 167 insertions, 172 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java deleted file mode 100644 index 6d73ee776e..0000000000 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.mapbox.mapboxsdk.testapp.activity.camera; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.design.widget.BottomSheetBehavior; -import android.support.v7.app.AppCompatActivity; -import android.view.View; - -import com.mapbox.mapboxsdk.annotations.MarkerOptions; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapbox.mapboxsdk.maps.MapView; -import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.maps.Style; -import com.mapbox.mapboxsdk.testapp.R; -import com.mapbox.mapboxsdk.testapp.view.LockableBottomSheetBehavior; - -import java.util.ArrayList; -import java.util.List; - -/** - * Test activity showcasing using the LatLngBounds camera API. - */ -public class LatLngBoundsActivity extends AppCompatActivity implements View.OnClickListener { - - private static final List<LatLng> LOCATIONS = new ArrayList<LatLng>() { - { - add(new LatLng(37.806866, -122.422502)); - add(new LatLng(37.812905, -122.477605)); - add(new LatLng(37.826944, -122.423188)); - add(new LatLng(37.752676, -122.447736)); - add(new LatLng(37.769305, -122.479322)); - add(new LatLng(37.749834, -122.417867)); - add(new LatLng(37.756149, -122.405679)); - add(new LatLng(37.751403, -122.387397)); - add(new LatLng(37.793064, -122.391517)); - add(new LatLng(37.769122, -122.427394)); - } - }; - private static final LatLngBounds BOUNDS = new LatLngBounds.Builder().includes(LOCATIONS).build(); - private static final int ANIMATION_DURATION_LONG = 450; - private static final int ANIMATION_DURATION_SHORT = 250; - private static final int BOUNDS_PADDING_DIVIDER_SMALL = 3; - private static final int BOUNDS_PADDING_DIVIDER_LARGE = 9; - - private MapView mapView; - private MapboxMap mapboxMap; - private View bottomSheet; - private LockableBottomSheetBehavior bottomSheetBehavior; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_latlngbounds); - initBottomSheet(); - initMapView(savedInstanceState); - } - - private void initMapView(Bundle savedInstanceState) { - mapView = findViewById(R.id.mapView); - mapView.onCreate(savedInstanceState); - mapView.getMapAsync(map -> { - mapboxMap = map; - disableGestures(); - moveToBounds(bottomSheet.getMeasuredHeight(), BOUNDS_PADDING_DIVIDER_SMALL, ANIMATION_DURATION_SHORT); - loadStyle(); - }); - } - - private void loadStyle() { - mapboxMap.setStyle(new Style.Builder().fromUri(Style.MAPBOX_STREETS), style -> { - addMarkers(); - initFab(); - }); - } - - private void disableGestures() { - mapboxMap.getUiSettings().setTiltGesturesEnabled(false); - mapboxMap.getUiSettings().setRotateGesturesEnabled(false); - } - - private void addMarkers() { - for (LatLng location : LOCATIONS) { - mapboxMap.addMarker(new MarkerOptions().position(location)); - } - } - - private void initFab() { - findViewById(R.id.fab).setOnClickListener(this); - } - - @Override - public void onClick(View v) { - bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - v.animate().alpha(0.0f).setDuration(ANIMATION_DURATION_SHORT); - } - - private void initBottomSheet() { - bottomSheet = findViewById(R.id.bottom_sheet); - bottomSheetBehavior = (LockableBottomSheetBehavior) BottomSheetBehavior.from(bottomSheet); - bottomSheetBehavior.setLocked(true); - bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { - @Override - public void onStateChanged(@NonNull View bottomSheet, int newState) { - if (newState == BottomSheetBehavior.STATE_SETTLING && mapboxMap != null) { - moveToBounds(0, BOUNDS_PADDING_DIVIDER_LARGE, ANIMATION_DURATION_LONG); - } - } - - @Override - public void onSlide(@NonNull View bottomSheet, float slideOffset) { - - } - }); - } - - private void moveToBounds(int verticalOffset, int boundsPaddingDivider, int duration) { - int paddingHorizontal = mapView.getMeasuredWidth() / boundsPaddingDivider; - int paddingVertical = (mapView.getMeasuredHeight() - verticalOffset) / boundsPaddingDivider; - mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds( - BOUNDS, - paddingHorizontal, - paddingVertical, - paddingHorizontal, - paddingVertical + verticalOffset), - duration - ); - } - - @Override - protected void onStart() { - super.onStart(); - mapView.onStart(); - } - - @Override - protected void onResume() { - super.onResume(); - mapView.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - mapView.onPause(); - } - - @Override - protected void onStop() { - super.onStop(); - mapView.onStop(); - } - - @Override - public void onLowMemory() { - super.onLowMemory(); - mapView.onLowMemory(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mapView.onDestroy(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - mapView.onSaveInstanceState(outState); - } -} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.kt new file mode 100644 index 0000000000..6f318f77eb --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.kt @@ -0,0 +1,167 @@ +package com.mapbox.mapboxsdk.testapp.activity.camera + +import android.content.Context +import android.os.Bundle +import android.support.design.widget.BottomSheetBehavior +import android.support.v7.app.AppCompatActivity +import android.view.View +import com.mapbox.geojson.FeatureCollection +import com.mapbox.geojson.FeatureCollection.fromJson +import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.geometry.LatLng +import com.mapbox.mapboxsdk.geometry.LatLngBounds +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.maps.Style +import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_CENTER +import com.mapbox.mapboxsdk.style.layers.PropertyFactory.* +import com.mapbox.mapboxsdk.style.layers.SymbolLayer +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import com.mapbox.mapboxsdk.testapp.R +import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil.loadStringFromAssets +import com.mapbox.mapboxsdk.utils.BitmapUtils +import kotlinx.android.synthetic.main.activity_latlngbounds.* +import java.net.URISyntaxException + +/** + * Test activity showcasing using the LatLngBounds camera API. + */ +class LatLngBoundsActivity : AppCompatActivity() { + + private lateinit var mapboxMap: MapboxMap + private lateinit var bottomSheetBehavior: BottomSheetBehavior<*> + private lateinit var bounds: LatLngBounds + + private val peekHeight by lazy { + 375.toPx(this) //375dp + } + + private val additionalPadding by lazy { + 32.toPx(this) //32dp + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_latlngbounds) + initMapView(savedInstanceState) + } + + private fun initMapView(savedInstanceState: Bundle?) { + mapView.onCreate(savedInstanceState) + mapView.getMapAsync { map -> + mapboxMap = map + + val featureCollection: FeatureCollection = fromJson(loadStringFromAssets(this, "points-sf.geojson")) + bounds = createBounds(featureCollection) + + map.getCameraForLatLngBounds(bounds, createPadding(peekHeight))?.let { + map.cameraPosition = it + } + + try { + loadStyle(featureCollection) + } catch (e: URISyntaxException) { + e.printStackTrace() + } + } + } + + private fun loadStyle(featureCollection: FeatureCollection) { + mapboxMap.setStyle(Style.Builder() + .fromUri(Style.MAPBOX_STREETS) + .withLayer(SymbolLayer("symbol", "symbol") + .withProperties( + iconAllowOverlap(true), + iconIgnorePlacement(true), + iconImage("icon"), + iconAnchor(ICON_ANCHOR_CENTER) + ) + ) + .withSource(GeoJsonSource("symbol", featureCollection)) + .withImage("icon", BitmapUtils.getDrawableFromRes(this@LatLngBoundsActivity, R.drawable.ic_android)!!) + ) { + initBottomSheet() + fab.setOnClickListener { bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED } + } + } + + private fun initBottomSheet() { + bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet) + bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) { + val offset = convertSlideOffset(slideOffset) + val bottomPadding = (peekHeight * offset).toInt() + + mapboxMap.getCameraForLatLngBounds(bounds, createPadding(bottomPadding))?.let { + mapboxMap.cameraPosition = it + } + } + + override fun onStateChanged(bottomSheet: View, newState: Int) { + // no-op + } + }) + } + + // slideOffset ranges from NaN to -1.0, range from 1.0 to 0 instead + fun convertSlideOffset(slideOffset: Float): Float { + return if (slideOffset.equals(Float.NaN)) { + 1.0f + } else { + 1 + slideOffset + } + } + + fun createPadding(bottomPadding: Int): IntArray { + return intArrayOf(additionalPadding, additionalPadding, additionalPadding, bottomPadding) + } + + private fun createBounds(featureCollection: FeatureCollection): LatLngBounds { + val boundsBuilder = LatLngBounds.Builder() + featureCollection.features()?.let { + for (feature in it) { + val point = feature.geometry() as Point + boundsBuilder.include(LatLng(point.latitude(), point.longitude())) + } + } + return boundsBuilder.build() + } + + override fun onStart() { + super.onStart() + mapView.onStart() + } + + override fun onResume() { + super.onResume() + mapView.onResume() + } + + override fun onPause() { + super.onPause() + mapView.onPause() + } + + override fun onStop() { + super.onStop() + mapView.onStop() + } + + override fun onLowMemory() { + super.onLowMemory() + mapView.onLowMemory() + } + + override fun onDestroy() { + super.onDestroy() + mapView.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + mapView.onSaveInstanceState(outState) + } + +} + +fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt() + |