自定义开发是android的必不可少的技能之一,要熟练的掌握,需要大家不断的学习,写代码才能日积月累。好了,废话不多说了;看下面的步骤:
1,用的到的两个地址https://www.amcharts.com/svg-maps/?map=china (需要下载国家的svg)

http://inloop.github.io/svg2android/ 下载后需要把svg文件在该地址中解析为Android可识别的代码


2,打开android studio—— res文件下,新建一个raw文件夹,然后把vsg文件复制粘贴到raw文件中,以下图是放入后的效果

3,在java中创建Java类继承View ,实现该类的构成函数,如下代码:
public class ChinaMapView extends View {
private Paint mPaint;
private Context context;
private int[] colors = new int[]{Color.RED, Color.GREEN, Color.YELLOW, Color.GREEN};
private ArrayList<ProvinceBean> itemList = new ArrayList<>();
private ProvinceBean selectItem;
private GestureDetectorCompat gestureDetectorCompat;
public ChinaMapView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
//准备画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);
this.context = context;
thread.start();
//手势处理类
gestureDetectorCompat = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
Log.d("event ", e.getAction() + "");
handlerTouch(e.getX(), e.getY());
return true;
}
});
}
private void handlerTouch(float x, float y) {
if (itemList != null) {
for (ProvinceBean item : itemList) {
if (item.isTouch((int) (x / 1.4), (int) (y / 1.4))) {
selectItem = item;
postInvalidate();
break;
}
}
}
}
public ChinaMapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetectorCompat.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(1.4f, 1.4f);
for (int i = 0; i < itemList.size(); i++) {
if (selectItem != itemList.get(i)) {
itemList.get(i).draw(mPaint, canvas, false);
}
}
if (selectItem != null) {
selectItem.draw(mPaint, canvas, true);
}
canvas.restore();
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg != null) {
postInvalidate();
}
}
};
Thread thread = new Thread() {
@Override
public void run() {
//dom解析xml
InputStream inputStream = context.getResources().openRawResource(R.raw.chinahigh);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);//解析输入流
Element rootElement = document.getDocumentElement();
NodeList items = rootElement.getElementsByTagName("path");
Log.d("MyMapView:", "集合大小=" + items.getLength());
for (int i = 0; i < items.getLength(); i++) {
int colorsIndex = i % 4;
Element element = (Element) items.item(i);
String pathData = element.getAttribute("android:pathData");
@SuppressLint("RestrictedApi") Path path = PathParser.createPathFromPathData(pathData);
ProvinceBean provinceBean = new ProvinceBean(path);
provinceBean.setColor(colors[colorsIndex]);
itemList.add(provinceBean);
}
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
class ProvinceBean {
private Path path;
private int color;
public ProvinceBean(Path path) {
this.path = path;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
/**
* 绘制省份
*
* @param paint
* @param canvas
* @param isSelected 是否被选中
*/
public void draw(Paint paint, Canvas canvas, boolean isSelected) {
if (isSelected) {
//绘制点击后的背景
paint.setStrokeWidth(2);
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
//添加阴影
paint.setShadowLayer(8, 0, 0, Color.BLACK);
canvas.drawPath(path, paint);
//绘制背景
paint.clearShadowLayer();
paint.setStrokeWidth(2);
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint);
} else {
//绘制背景
paint.setStrokeWidth(2);
paint.clearShadowLayer();
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint);
//绘制边界线
paint.setStrokeWidth(1);
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, paint);
}
}
//触摸点是否在这个省的path内
public boolean isTouch(int x, int y) {
//构造一个矩形对象
RectF rectF = new RectF();
//返回路径控制点的计算边界保存到rectF
path.computeBounds(rectF, true);
//构造一个区域对象
Region region = new Region();
//给区赋值
region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
return region.contains(x, y);
}
}
4,在主类中调用该自定义的类:

需要注意的一些坑:
1.2、添加
compile 'com.android.support:appcompat-v7:25.3.1' //需要是23.2 版本以上的
1.3、Activity需要继承与AppCompatActivity
1.4、布局文件当中添加
xmlns:app="http://schemas.android.com/apk/res-auto"
2、使用在Actvity前面添加一个flag设置
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
2.1 ImageView/ImageButton
XML app:srcCompat
代码里面使用无区别
2.2 Button 不支持app:srcCompat
Xml 使用在Button的selector
2.3 RadioButton 直接使用
2.4 textview的drawable 直接使用
2.5 使用的动态Vector Drawable
主要是不能直接修改 pathData
不能使用自定义interpolator
最后
以上就是鳗鱼砖头最近收集整理的关于Android 开发自定义使用svg构造交互式中国(各国)地图的全部内容,更多相关Android内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复