美文网首页
Android--SVG打造可交互式中国地图

Android--SVG打造可交互式中国地图

作者: aruba | 来源:发表于2020-02-07 16:46 被阅读0次
    效果如下:
    MapView.gif
    首先我们需要一张svg的中国地图图片
    svg目录.jpg 在浏览器打开.jpg
    第一步:将svg转换为安卓中的vector(利用插件或网站http://inloop.github.io/svg2android/
    第二步,自定义View解析xml,将所有Path标签转换为我们安卓的Path对象
        private Thread ParseThread = new Thread(new Runnable() {
            @Override
            public void run() {
                InputStream inputStream = getContext().getResources().openRawResource(rawId);
                try {
                    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                    Document document = builder.parse(inputStream);
                    Element root = document.getDocumentElement();//获取根节点
                    NodeList nodeList = root.getElementsByTagName("path");
    
                    provinceItems = new ArrayList<>(nodeList.getLength());
                    for (int i = 0; i < nodeList.getLength(); i++) {
                        Element element = (Element) nodeList.item(i);//path节点
                        //解析pathData属性
                        ProvinceItem provinceItem = new ProvinceItem();
                        provinceItem.setPath(PathParser.createPathFromPathData(element.getAttribute("android:pathData")));
                        provinceItems.add(provinceItem);
                    }
    
                    postInvalidate();
                } catch (ParserConfigurationException | IOException | SAXException e) {
                    e.printStackTrace();
                }
            }
        });
    
    第三步,在onDraw方法中画出path集合
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.save();
            canvas.scale(scale, scale);
            for (ProvinceItem provinceItem : provinceItems) {
                if (selectItem != provinceItem)
                    provinceItem.drawPath(canvas, mPaint, false);
            }
    
            if (selectItem != null) selectItem.drawPath(canvas, mPaint, true);
            canvas.restore();
        }
    
    第四步,改写onTouchEvent方法,判断是否触摸到省份
      @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    return true;
                case MotionEvent.ACTION_UP: {
                    ProvinceItem temp = null;
                    for (ProvinceItem provinceItem : provinceItems) {
                        if (provinceItem.isOnTouch(event.getX() / scale, event.getY() / scale)) {
                            temp = provinceItem;
                            break;
                        }
                    }
    
                    if (temp != null) {
                        selectItem = temp;
                        postInvalidate();
                    }
                }
            }
            return super.onTouchEvent(event);
        }
    
    利用Region的contains方法判断抬起坐标是否在path范围内
        public boolean isOnTouch(float x, float y) {
            Region region = new Region();
            RectF rect = new RectF();
            path.computeBounds(rect, true);
            region.setPath(path, new Region((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom));
    
            return region.contains((int) x, (int) y);
        }
    
    项目地址:https://gitee.com/aruba/VectorApplication.git

    相关文章

      网友评论

          本文标题:Android--SVG打造可交互式中国地图

          本文链接:https://www.haomeiwen.com/subject/umwmxhtx.html