Skip to content

Commit 9949dd4

Browse files
committed
Polyline/polygon styling
Change-Id: I5a568aa81af6e000ff99579fd1f3caa212bd24e4
1 parent 8605faa commit 9949dd4

File tree

9 files changed

+680
-271
lines changed

9 files changed

+680
-271
lines changed

ApiDemos/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ dependencies {
2323
compile fileTree(dir: 'libs', include: ['*.jar'])
2424
testCompile 'junit:junit:4.12'
2525
compile 'com.android.support:appcompat-v7:23.4.0'
26-
compile 'com.google.android.gms:play-services-maps:9.8.0'
26+
compile 'com.google.android.gms:play-services-maps:10.2.0'
2727
}

ApiDemos/app/src/main/java/com/example/mapdemo/CircleDemoActivity.java

Lines changed: 170 additions & 93 deletions
Large diffs are not rendered by default.

ApiDemos/app/src/main/java/com/example/mapdemo/PolygonDemoActivity.java

Lines changed: 159 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,26 @@
2020
import com.google.android.gms.maps.GoogleMap;
2121
import com.google.android.gms.maps.OnMapReadyCallback;
2222
import com.google.android.gms.maps.SupportMapFragment;
23+
import com.google.android.gms.maps.model.Dash;
24+
import com.google.android.gms.maps.model.Dot;
25+
import com.google.android.gms.maps.model.Gap;
26+
import com.google.android.gms.maps.model.JointType;
2327
import com.google.android.gms.maps.model.LatLng;
28+
import com.google.android.gms.maps.model.PatternItem;
2429
import com.google.android.gms.maps.model.Polygon;
2530
import com.google.android.gms.maps.model.PolygonOptions;
2631

2732
import android.graphics.Color;
2833
import android.os.Bundle;
2934
import android.support.v7.app.AppCompatActivity;
3035
import android.view.View;
36+
import android.widget.AdapterView;
37+
import android.widget.AdapterView.OnItemSelectedListener;
38+
import android.widget.ArrayAdapter;
3139
import android.widget.CheckBox;
3240
import android.widget.SeekBar;
3341
import android.widget.SeekBar.OnSeekBarChangeListener;
42+
import android.widget.Spinner;
3443

3544
import java.util.Arrays;
3645
import java.util.List;
@@ -39,44 +48,82 @@
3948
* This shows how to draw polygons on a map.
4049
*/
4150
public class PolygonDemoActivity extends AppCompatActivity
42-
implements OnSeekBarChangeListener, OnMapReadyCallback {
43-
44-
private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
45-
46-
private static final int WIDTH_MAX = 50;
47-
48-
private static final int HUE_MAX = 360;
49-
50-
private static final int ALPHA_MAX = 255;
51+
implements OnSeekBarChangeListener, OnItemSelectedListener, OnMapReadyCallback {
52+
53+
private static final LatLng CENTER = new LatLng(-20, 130);
54+
private static final int MAX_WIDTH_PX = 100;
55+
private static final int MAX_HUE_DEGREES = 360;
56+
private static final int MAX_ALPHA = 255;
57+
58+
private static final int PATTERN_DASH_LENGTH_PX = 50;
59+
private static final int PATTERN_GAP_LENGTH_PX = 10;
60+
private static final Dot DOT = new Dot();
61+
private static final Dash DASH = new Dash(PATTERN_DASH_LENGTH_PX);
62+
private static final Gap GAP = new Gap(PATTERN_GAP_LENGTH_PX);
63+
private static final List<PatternItem> PATTERN_DOTTED = Arrays.asList(DOT, GAP);
64+
private static final List<PatternItem> PATTERN_DASHED = Arrays.asList(DASH, GAP);
65+
private static final List<PatternItem> PATTERN_MIXED = Arrays.asList(DOT, GAP, DOT, DASH, GAP);
5166

5267
private Polygon mMutablePolygon;
68+
private SeekBar mFillHueBar;
69+
private SeekBar mFillAlphaBar;
70+
private SeekBar mStrokeWidthBar;
71+
private SeekBar mStrokeHueBar;
72+
private SeekBar mStrokeAlphaBar;
73+
private Spinner mStrokeJointTypeSpinner;
74+
private Spinner mStrokePatternSpinner;
75+
private CheckBox mClickabilityCheckbox;
5376

54-
private Polygon mClickablePolygonWithHoles;
55-
56-
private SeekBar mColorBar;
57-
58-
private SeekBar mAlphaBar;
77+
// These are the options for polygon stroke joints and patterns. We use their
78+
// string resource IDs as identifiers.
5979

60-
private SeekBar mWidthBar;
80+
private static final int[] JOINT_TYPE_NAME_RESOURCE_IDS = {
81+
R.string.joint_type_default, // Default
82+
R.string.joint_type_bevel,
83+
R.string.joint_type_round,
84+
};
6185

62-
private CheckBox mClickabilityCheckbox;
86+
private static final int[] PATTERN_TYPE_NAME_RESOURCE_IDS = {
87+
R.string.pattern_solid, // Default
88+
R.string.pattern_dashed,
89+
R.string.pattern_dotted,
90+
R.string.pattern_mixed,
91+
};
6392

6493
@Override
6594
protected void onCreate(Bundle savedInstanceState) {
6695
super.onCreate(savedInstanceState);
6796
setContentView(R.layout.polygon_demo);
6897

69-
mColorBar = (SeekBar) findViewById(R.id.hueSeekBar);
70-
mColorBar.setMax(HUE_MAX);
71-
mColorBar.setProgress(0);
98+
mFillHueBar = (SeekBar) findViewById(R.id.fillHueSeekBar);
99+
mFillHueBar.setMax(MAX_HUE_DEGREES);
100+
mFillHueBar.setProgress(MAX_HUE_DEGREES / 2);
101+
102+
mFillAlphaBar = (SeekBar) findViewById(R.id.fillAlphaSeekBar);
103+
mFillAlphaBar.setMax(MAX_ALPHA);
104+
mFillAlphaBar.setProgress(MAX_ALPHA / 2);
72105

73-
mAlphaBar = (SeekBar) findViewById(R.id.alphaSeekBar);
74-
mAlphaBar.setMax(ALPHA_MAX);
75-
mAlphaBar.setProgress(127);
106+
mStrokeWidthBar = (SeekBar) findViewById(R.id.strokeWidthSeekBar);
107+
mStrokeWidthBar.setMax(MAX_WIDTH_PX);
108+
mStrokeWidthBar.setProgress(MAX_WIDTH_PX / 3);
76109

77-
mWidthBar = (SeekBar) findViewById(R.id.widthSeekBar);
78-
mWidthBar.setMax(WIDTH_MAX);
79-
mWidthBar.setProgress(10);
110+
mStrokeHueBar = (SeekBar) findViewById(R.id.strokeHueSeekBar);
111+
mStrokeHueBar.setMax(MAX_HUE_DEGREES);
112+
mStrokeHueBar.setProgress(0);
113+
114+
mStrokeAlphaBar = (SeekBar) findViewById(R.id.strokeAlphaSeekBar);
115+
mStrokeAlphaBar.setMax(MAX_ALPHA);
116+
mStrokeAlphaBar.setProgress(MAX_ALPHA);
117+
118+
mStrokeJointTypeSpinner = (Spinner) findViewById(R.id.strokeJointTypeSpinner);
119+
mStrokeJointTypeSpinner.setAdapter(new ArrayAdapter<>(
120+
this, android.R.layout.simple_spinner_item,
121+
getResourceStrings(JOINT_TYPE_NAME_RESOURCE_IDS)));
122+
123+
mStrokePatternSpinner = (Spinner) findViewById(R.id.strokePatternSpinner);
124+
mStrokePatternSpinner.setAdapter(new ArrayAdapter<>(
125+
this, android.R.layout.simple_spinner_item,
126+
getResourceStrings(PATTERN_TYPE_NAME_RESOURCE_IDS)));
80127

81128
mClickabilityCheckbox = (CheckBox) findViewById(R.id.toggleClickability);
82129

@@ -85,55 +132,53 @@ protected void onCreate(Bundle savedInstanceState) {
85132
mapFragment.getMapAsync(this);
86133
}
87134

135+
private String[] getResourceStrings(int[] resourceIds) {
136+
String[] strings = new String[resourceIds.length];
137+
for (int i = 0; i < resourceIds.length; i++) {
138+
strings[i] = getString(resourceIds[i]);
139+
}
140+
return strings;
141+
}
142+
88143
@Override
89144
public void onMapReady(GoogleMap map) {
90145
// Override the default content description on the view, for accessibility mode.
91-
// Ideally this string would be localised.
92-
map.setContentDescription("Google Map with polygons.");
146+
map.setContentDescription(getString(R.string.polygon_demo_description));
147+
148+
int fillColorArgb = Color.HSVToColor(
149+
mFillAlphaBar.getProgress(), new float[]{mFillHueBar.getProgress(), 1, 1});
150+
int strokeColorArgb = Color.HSVToColor(
151+
mStrokeAlphaBar.getProgress(), new float[]{mStrokeHueBar.getProgress(), 1, 1});
93152

94153
// Create a rectangle with two rectangular holes.
95-
mClickablePolygonWithHoles = map.addPolygon(new PolygonOptions()
96-
.addAll(createRectangle(new LatLng(-20, 130), 5, 5))
154+
mMutablePolygon = map.addPolygon(new PolygonOptions()
155+
.addAll(createRectangle(CENTER, 5, 5))
97156
.addHole(createRectangle(new LatLng(-22, 128), 1, 1))
98157
.addHole(createRectangle(new LatLng(-18, 133), 0.5, 1.5))
99-
.fillColor(Color.CYAN)
100-
.strokeColor(Color.BLUE)
101-
.strokeWidth(5)
158+
.fillColor(fillColorArgb)
159+
.strokeColor(strokeColorArgb)
160+
.strokeWidth(mStrokeWidthBar.getProgress())
102161
.clickable(mClickabilityCheckbox.isChecked()));
103162

104-
// Create a rectangle centered at Sydney.
105-
PolygonOptions options = new PolygonOptions()
106-
.addAll(createRectangle(SYDNEY, 5, 8))
107-
.clickable(mClickabilityCheckbox.isChecked());
108-
109-
int fillColor = Color.HSVToColor(
110-
mAlphaBar.getProgress(), new float[]{mColorBar.getProgress(), 1, 1});
111-
mMutablePolygon = map.addPolygon(options
112-
.strokeWidth(mWidthBar.getProgress())
113-
.strokeColor(Color.BLACK)
114-
.fillColor(fillColor));
115-
116-
// Create another polygon that overlaps the previous two.
117-
// Clickability defaults to false, so this one won't accept clicks.
118-
map.addPolygon(new PolygonOptions()
119-
.addAll(createRectangle(new LatLng(-27, 140), 10, 7))
120-
.fillColor(Color.WHITE)
121-
.strokeColor(Color.BLACK));
122-
123-
mColorBar.setOnSeekBarChangeListener(this);
124-
mAlphaBar.setOnSeekBarChangeListener(this);
125-
mWidthBar.setOnSeekBarChangeListener(this);
163+
mFillHueBar.setOnSeekBarChangeListener(this);
164+
mFillAlphaBar.setOnSeekBarChangeListener(this);
165+
166+
mStrokeWidthBar.setOnSeekBarChangeListener(this);
167+
mStrokeHueBar.setOnSeekBarChangeListener(this);
168+
mStrokeAlphaBar.setOnSeekBarChangeListener(this);
169+
170+
mStrokeJointTypeSpinner.setOnItemSelectedListener(this);
171+
mStrokePatternSpinner.setOnItemSelectedListener(this);
126172

127173
// Move the map so that it is centered on the mutable polygon.
128-
map.moveCamera(CameraUpdateFactory.newLatLng(SYDNEY));
174+
map.moveCamera(CameraUpdateFactory.newLatLngZoom(CENTER, 4));
129175

130176
// Add a listener for polygon clicks that changes the clicked polygon's stroke color.
131177
map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
132178
@Override
133179
public void onPolygonClick(Polygon polygon) {
134-
// Flip the r, g and b components of the polygon's stroke color.
135-
int strokeColor = polygon.getStrokeColor() ^ 0x00ffffff;
136-
polygon.setStrokeColor(strokeColor);
180+
// Flip the red, green and blue components of the polygon's stroke color.
181+
polygon.setStrokeColor(polygon.getStrokeColor() ^ 0x00ffffff);
137182
}
138183
});
139184
}
@@ -149,6 +194,50 @@ private List<LatLng> createRectangle(LatLng center, double halfWidth, double hal
149194
new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));
150195
}
151196

197+
private int getSelectedJointType(int pos) {
198+
switch (JOINT_TYPE_NAME_RESOURCE_IDS[pos]) {
199+
case R.string.joint_type_bevel:
200+
return JointType.BEVEL;
201+
case R.string.joint_type_round:
202+
return JointType.ROUND;
203+
case R.string.joint_type_default:
204+
return JointType.DEFAULT;
205+
}
206+
return 0;
207+
}
208+
209+
private List<PatternItem> getSelectedPattern(int pos) {
210+
switch (PATTERN_TYPE_NAME_RESOURCE_IDS[pos]) {
211+
case R.string.pattern_solid:
212+
return null;
213+
case R.string.pattern_dotted:
214+
return PATTERN_DOTTED;
215+
case R.string.pattern_dashed:
216+
return PATTERN_DASHED;
217+
case R.string.pattern_mixed:
218+
return PATTERN_MIXED;
219+
default:
220+
return null;
221+
}
222+
}
223+
224+
@Override
225+
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
226+
switch (parent.getId()) {
227+
case R.id.strokeJointTypeSpinner:
228+
mMutablePolygon.setStrokeJointType(getSelectedJointType(pos));
229+
break;
230+
case R.id.strokePatternSpinner:
231+
mMutablePolygon.setStrokePattern(getSelectedPattern(pos));
232+
break;
233+
}
234+
}
235+
236+
@Override
237+
public void onNothingSelected(AdapterView<?> parent) {
238+
// Don't do anything here.
239+
}
240+
152241
@Override
153242
public void onStopTrackingTouch(SeekBar seekBar) {
154243
// Don't do anything here.
@@ -165,28 +254,33 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
165254
return;
166255
}
167256

168-
if (seekBar == mColorBar) {
257+
if (seekBar == mFillHueBar) {
169258
mMutablePolygon.setFillColor(Color.HSVToColor(
170259
Color.alpha(mMutablePolygon.getFillColor()), new float[]{progress, 1, 1}));
171-
} else if (seekBar == mAlphaBar) {
260+
} else if (seekBar == mFillAlphaBar) {
172261
int prevColor = mMutablePolygon.getFillColor();
173262
mMutablePolygon.setFillColor(Color.argb(
174263
progress, Color.red(prevColor), Color.green(prevColor),
175264
Color.blue(prevColor)));
176-
} else if (seekBar == mWidthBar) {
265+
} else if (seekBar == mStrokeHueBar) {
266+
mMutablePolygon.setStrokeColor(Color.HSVToColor(
267+
Color.alpha(mMutablePolygon.getStrokeColor()), new float[]{progress, 1, 1}));
268+
} else if (seekBar == mStrokeAlphaBar) {
269+
int prevColorArgb = mMutablePolygon.getStrokeColor();
270+
mMutablePolygon.setStrokeColor(Color.argb(
271+
progress, Color.red(prevColorArgb), Color.green(prevColorArgb),
272+
Color.blue(prevColorArgb)));
273+
} else if (seekBar == mStrokeWidthBar) {
177274
mMutablePolygon.setStrokeWidth(progress);
178275
}
179276
}
180277

181278
/**
182-
* Toggles the clickability of two polygons based on the state of the View that triggered this
279+
* Toggles the clickability of the polygon based on the state of the View that triggered this
183280
* call.
184281
* This callback is defined on the CheckBox in the layout for this Activity.
185282
*/
186283
public void toggleClickability(View view) {
187-
if (mClickablePolygonWithHoles != null) {
188-
mClickablePolygonWithHoles.setClickable(((CheckBox) view).isChecked());
189-
}
190284
if (mMutablePolygon != null) {
191285
mMutablePolygon.setClickable(((CheckBox) view).isChecked());
192286
}

0 commit comments

Comments
 (0)