1.下载SVG文件
下载地址: https://www.amcharts.com/dl/javascript-maps/
2.svg转换为xml文件(可选,也可以直接解析svg文件)
svg转换为xml文件地址:http://inloop.github.io/svg2android/
AndroidStudio可以安装一个SVG2VectorDrawable 直接进行转换
首先先把下载好的svg文件放到raw目录下面 ps:下载下来的文件有大小写,放到raw目录下面只能全部小写,不然编译报错
接下来通过java代码将svg文件解析成为List 集合
public void getCityItemList() {
new Thread() {
@Override
public void run() {
try {
List result = new ArrayList<>();
long startTime = System.currentTimeMillis();
InputStream inputStream = mContext.getResources().openRawResource(R.raw.china);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(inputStream, "utf-8");
int eventType;
while ((eventType = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = parser.getName();
if ("path".equals(name)) {
String id = parser.getAttributeValue(null, "id");
String title = parser.getAttributeValue(null, "title");
String pathData = parser.getAttributeValue(null, "d");
Path path = PathParser.createPathFromPathData(pathData);
Region region = new Region();
if (path != null) {
RectF r = new RectF();
//得到Path的矩形边界
path.computeBounds(r, true);
// 设置区域路径和剪辑描述的区域
region.setPath(path, new Region((int) (r.left), (int) (r.top), (int) (r.right), (int) (r.bottom)));
}
CityItem cityItem = new CityItem();
cityItem.setCityId(id);
cityItem.setCityName(title);
cityItem.setmPath(path);
cityItem.setmRegion(region);
result.add(cityItem);
}
}
parser.next();
}
Message msg = Message.obtain();
msg.what = LOAD_FINISH;
msg.obj = result;
mHander.sendMessage(msg);
Log.d("TAG", "加载SVG数据结束耗时->" + (System.currentTimeMillis() - startTime));
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
svg文件里面的一个path节点对应解析成一个CityItem ,这样就可以遍历解析得到的List 数据去绘制出每一个Path
for (CityItem cityItem : list) {
if (!cityItem.equals(selectCity))
cityItem.onDraw(canvas, mPaint, false);
}
完成当前操作效果如下
接下来就是加上交互效果,当点击某一个省份的时候,需要给当前选中的省份加上一个描边和不同的颜色。此时实现View的OnTouch方法,去判读用户点击的点是否包含于地图中的某一个省份,如果包含则将当前省份绘制为选中状态
/**
* 处理点击事件
*
* @param x 点击的X坐标
* @param y 点击的Y坐标
*/
private boolean handlerTouch(int x, int y) {
final List list = cityItemList;
CityItem cityItem = null;
if (list == null) return false;
for (CityItem temp : list) {
if (temp.isOnTouch((int) (x / scale), (int) (y / scale))) {//除以放大倍数
cityItem = temp;
break;
}
}
if (cityItem != null && !cityItem.equals(selectCity)) {
selectCity = cityItem;
onMapClickListener.onClick(selectCity);
postInvalidate();
}
return selectCity != null;
}
这样就去别出了选中和未选中的省份,同时通过onMapClickListener接口将选中的数据回调,接下来就是绘制出不同状态的地图
public void onDraw(Canvas canvas, Paint paint, boolean isSelected) {
if (isSelected) {
paint.setStrokeWidth(2);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
paint.setShadowLayer(8, 0, 0, 0xFFFFFFFF);
canvas.drawPath(mPath, paint);
paint.clearShadowLayer();
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(2);
canvas.drawPath(mPath, paint);
} else {
paint.clearShadowLayer();
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.FILL);
paint.setColor(drawColor);
canvas.drawPath(mPath, paint);
paint.setStyle(Paint.Style.STROKE);
int strokeColor = 0xFFD0E8F4;
paint.setColor(strokeColor);
canvas.drawPath(mPath, paint);
}
}
这样就基本实现一个简单地图的绘制与交互
项目源码 github ps:model->pathmap