Интерактивная SVG карта в Android

Имеется svg-карта, необходимо создать Android-приложение показывающее эту карту и реагирующую на клики по регионам.

Для этого нам понадобятся
android.webkit.WebView для отображения SVG и android.webkit.JavascriptInterface для доступа к java-объектам с JavaScript

Для начала создадим простую  карту (map.svg) состоящую из двух кругов. При клике на каждую из них будет вызываться JavaScript-функция click(evt), в нем мы определяем название и id региона и вызываем через JavascriptInterface метод Android.regionActivity(name)

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="420mm" height="594mm" version="1.1" style="shape-rendering: geometricPrecision; text-rendering: geometricPrecision; fill-rule: evenodd; clip-rule: evenodd; height: 100%; width: 100%;" viewBox="0 0 42000 59400">

  <script type="application/ecmascript"> <![CDATA[
    var last_region;

    function click(evt) {
      if(evt.target.parentNode.getAttribute("class") == "region") {
        regionClick(evt.target.parentNode);
      }
    }

    function regionClick(region) {
      console.log(region.id + " " + region.getAttribute("data-region-id"));
      
      if(!!last_region) {
        last_region.style.opacity= 1;
      }
      
      region.style.opacity= 0.5;
      last_region = region;
      Android.regionActivity(region.id);
    }
  ]]> </script>
  
 <g id="regions" onclick="click(evt)">
  <g id="Большой регион" class="region" data-region-id="1">
   <circle cx="150" cy="5150" r="1140" fill="red" />
  </g>
  <g id="Малый регион" class="region" data-region-id="2">
   <circle cx="5000" cy="7000" r="840"  fill="blue" />
   </g>
</g>
</svg>

затем создадим простой проект с пустым MainActivity и отредактируем его следующим образом

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    public static String REGION_MESSAGE = "regionName";
    private WebView webView;

    // Создадим интерфейс для взаимодействия с JavaScript в SVG 
    public class WebAppInterface {
        @JavascriptInterface
        public void regionActivity(String toast) {
            Intent intent = new Intent(MainActivity.this, RegionActivity.class);
            String message = toast;
            intent.putExtra(MainActivity.REGION_MESSAGE, message);
            startActivity(intent);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDefaultTextEncodingName("utf-8");
        webView.getSettings().setBuiltInZoomControls(true);
        // Объявим ранее созданный интерфейс 
        // Теперь чтобы получить доступ к методам WebAppInterface,
        // достаточно вызвать, например, Android.regionActivity(name)
        webView.addJavascriptInterface(new WebAppInterface(), "Android");

        // Ну и непосредственно открываем нашу карту
        webView.loadUrl("file:///android_asset/map.svg");
    }
}

И добавим нашу ранее созданную карту (map.svg) в наш проект в папку src/main/assets. Ну и не забудем добавить еще и RegionActivity.

На этом все.

Интерактивная SVG карта в Android: 3 комментария

  1. Что имеется ввиду под «Ну и не забудем добавить еще и RegionActivity.»? Можете это раскрыть?

  2. В данном случае, RegionActivity это активити, которая которая отображает подробную информацию выбранного региона. Я не стал заострять на него внимания.

Добавить комментарий для Сергей Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *