1+ package com .mapbox .mapboxandroiddemo .examples .dds ;
2+
3+ // #-code-snippet: animated-dash-line full-java
4+
5+ import android .graphics .Color ;
6+ import android .os .Bundle ;
7+ import android .os .Handler ;
8+ import android .support .v7 .app .AppCompatActivity ;
9+ import android .util .Log ;
10+
11+ import com .mapbox .mapboxandroiddemo .R ;
12+ import com .mapbox .mapboxsdk .Mapbox ;
13+ import com .mapbox .mapboxsdk .maps .MapView ;
14+ import com .mapbox .mapboxsdk .maps .MapboxMap ;
15+ import com .mapbox .mapboxsdk .maps .OnMapReadyCallback ;
16+ import com .mapbox .mapboxsdk .style .layers .LineLayer ;
17+ import com .mapbox .mapboxsdk .style .sources .GeoJsonSource ;
18+
19+ import java .net .MalformedURLException ;
20+ import java .net .URL ;
21+
22+ import static com .mapbox .mapboxsdk .style .layers .Property .LINE_CAP_ROUND ;
23+ import static com .mapbox .mapboxsdk .style .layers .Property .LINE_JOIN_ROUND ;
24+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineCap ;
25+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineColor ;
26+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineDasharray ;
27+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineJoin ;
28+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineWidth ;
29+
30+ /**
31+ * Create an effect of animated and moving LineLayer dashes by rapidly adjusting the
32+ * dash and gap lengths.
33+ */
34+ public class AnimatedDashLineActivity extends AppCompatActivity implements OnMapReadyCallback {
35+
36+ private MapView mapView ;
37+ private MapboxMap mapboxMap ;
38+ private Handler handler ;
39+ private String tag = "AnimatedDashLine" ;
40+ private RefreshDashAndGapRunnable refreshDashAndGapRunnable ;
41+ private int animationSpeedMillseconds = 50 ;
42+
43+ @ Override
44+ protected void onCreate (Bundle savedInstanceState ) {
45+ super .onCreate (savedInstanceState );
46+
47+ // Mapbox access token is configured here. This needs to be called either in your application
48+ // object or in the same activity which contains the mapview.
49+ Mapbox .getInstance (this , getString (R .string .access_token ));
50+
51+ // This contains the MapView in XML and needs to be called after the access token is configured.
52+ setContentView (R .layout .activity_animated_dash_line );
53+
54+ handler = new Handler ();
55+ mapView = findViewById (R .id .mapView );
56+ mapView .onCreate (savedInstanceState );
57+ mapView .getMapAsync (this );
58+ }
59+
60+ @ Override
61+ public void onMapReady (MapboxMap mapboxMap ) {
62+ AnimatedDashLineActivity .this .mapboxMap = mapboxMap ;
63+ initBikePathLayer ();
64+ Log .d (tag , "onMapReady: here 1" );
65+ Runnable runnable = new RefreshDashAndGapRunnable ();
66+ Log .d (tag , "onMapReady: runnable made" );
67+ handler .postDelayed (runnable , animationSpeedMillseconds );
68+ Log .d (tag , "onMapReady: here 2" );
69+ }
70+
71+ private void initBikePathLayer () {
72+ try {
73+ GeoJsonSource geoJsonSource = new GeoJsonSource ("animated_line_source" , new URL (
74+ "https://raw.githubusercontent.com/Chicago/osd-bike-routes/master/data/Bikeroutes.geojson"
75+ ));
76+ mapboxMap .addSource (geoJsonSource );
77+ LineLayer animatedDashBikeLineLayer = new LineLayer ("animated_line_layer_id" , "animated_line_source" );
78+ animatedDashBikeLineLayer .withProperties (
79+ lineWidth (4.5f ),
80+ lineColor (Color .parseColor ("#bf42f4" )),
81+ lineCap (LINE_CAP_ROUND ),
82+ lineJoin (LINE_JOIN_ROUND )
83+ );
84+ mapboxMap .addLayer (animatedDashBikeLineLayer );
85+ } catch (MalformedURLException malformedUrlException ) {
86+ Log .d ("AnimatedDashLine" , "Check the URL: " + malformedUrlException .getMessage ());
87+ }
88+ }
89+
90+ private class RefreshDashAndGapRunnable implements Runnable {
91+
92+ private float valueOne , valueTwo , valueThree , valueFour , ValueFive ;
93+ private float dashLength = 1 ;
94+ private float gapLength = 3 ;
95+
96+ // We divide the animation up into 40 totalNumberOfSteps to make careful use of the finite space in
97+ // LineAtlas
98+ private float totalNumberOfSteps = 40 ;
99+
100+ // A # of totalNumberOfSteps proportional to the dashLength are devoted to manipulating the dash
101+ private float dashSteps = totalNumberOfSteps * dashLength / (gapLength + dashLength );
102+
103+ // A # of totalNumberOfSteps proportional to the gapLength are devoted to manipulating the gap
104+ private float gapSteps = totalNumberOfSteps - dashSteps ;
105+
106+ // The current currentStep #
107+ private int currentStep = 0 ;
108+
109+ private String TAG = "AnimatedDashLine" ;
110+
111+ @ Override
112+ public void run () {
113+ Log .d (TAG , "RefreshDashAndGapRunnable run: " );
114+ currentStep = currentStep + 1 ;
115+ if (currentStep >= totalNumberOfSteps ) {
116+ currentStep = 0 ;
117+ }
118+ if (currentStep < dashSteps ) {
119+ valueOne = currentStep / dashSteps ;
120+ valueTwo = (1 - valueOne ) * dashLength ;
121+ valueThree = gapLength ;
122+ valueFour = valueOne * dashLength ;
123+ ValueFive = 0 ;
124+ } else {
125+ valueOne = (currentStep - dashSteps ) / (gapSteps );
126+ valueTwo = 0 ;
127+ valueThree = (1 - valueOne ) * gapLength ;
128+ valueFour = dashLength ;
129+ ValueFive = valueOne * gapLength ;
130+ }
131+ Log .d (TAG , "RefreshDashAndGapRunnable run: here" );
132+
133+ Float [] newFloatArray = new Float [] {valueTwo , valueThree , valueFour , ValueFive };
134+
135+ mapboxMap .getLayer ("animated_line_layer_id" ).setProperties (
136+ lineDasharray (newFloatArray ));
137+ Log .d (TAG , "RefreshDashAndGapRunnable run: layer done being gotten" );
138+ handler .postDelayed (this , animationSpeedMillseconds );
139+ }
140+ }
141+
142+ // Add the mapView lifecycle to the activity's lifecycle methods
143+ @ Override
144+ public void onResume () {
145+ super .onResume ();
146+ mapView .onResume ();
147+ }
148+
149+ @ Override
150+ protected void onStart () {
151+ super .onStart ();
152+ mapView .onStart ();
153+ }
154+
155+ @ Override
156+ protected void onStop () {
157+ super .onStop ();
158+ mapView .onStop ();
159+ }
160+
161+ @ Override
162+ public void onPause () {
163+ super .onPause ();
164+ mapView .onPause ();
165+ }
166+
167+ @ Override
168+ public void onLowMemory () {
169+ super .onLowMemory ();
170+ mapView .onLowMemory ();
171+ }
172+
173+ @ Override
174+ protected void onDestroy () {
175+ super .onDestroy ();
176+ mapView .onDestroy ();
177+ handler .removeCallbacks (refreshDashAndGapRunnable );
178+ refreshDashAndGapRunnable = null ;
179+ handler = null ;
180+ }
181+
182+ @ Override
183+ protected void onSaveInstanceState (Bundle outState ) {
184+ super .onSaveInstanceState (outState );
185+ mapView .onSaveInstanceState (outState );
186+ }
187+ }
188+ // #-end-code-snippet: animated-dash-line full-java
0 commit comments