Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android image map. - displaying an .svg and using it as an image map (touch zones)

I am looking for a way to display an image and have the user tap on different parts of the image to navigate and perform actions.

I was considering using an invisible color map to check which parts have been touched.

But since i also want to highlight the selected areas, i was thinking of using vectors. There is a nice library to render svg files into an image view here, but it doesn't handle touches.
Is there a library out there that does? Or any smarter way of doing this?

(I also checked out this project but it won't swallow .svg files and my vector image is far too complex to insert all the data by hand)

like image 829
pumpkee Avatar asked Jul 09 '13 08:07

pumpkee


People also ask

Can Android read SVG files?

You can import an SVG file as a VectorDrawable in Android Studio, follow these steps : "Right-click" on the res folder and select new > Vector Asset. Select the Local File option and browse to your . svg file.


2 Answers

Interesting problem! I'm not convinced you can't use a combination of the libraries you mentioned.

What I would do is first use SVG-Android to programmatically read in your SVG file. Looking at SVG-Android, it looks like it returns the final product as a PictureDrawable, which is a subclass of Drawable.

Right after SVG-Android finishes processing the SVG graphics, I'd use ImageView.setImageDrawable to load the main ImageView with the PictureDrawable we just generated. Then I'd just use that ImageView as the base for the implementation of "Images with Clickable Areas" you linked in the original question.

Honestly, I think the hardest part will be getting SVG-Android to work correctly (I've played with it a bit, and it's a bit finicky). However, I don't think you'll have much difficulty combining the SVG-generated drawable with the clickable areas. It's a simple change in the source of the base image.

Good luck!

like image 112
Brian Avatar answered Oct 08 '22 19:10

Brian


Not sure if this is the sort of thing you are after but here is an example of click enabled svg in a Android WebView:

WebView webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://www.w3.org/TR/SVG/images/script/script01.svg");

It should show a red circle that you can click on and the circle changes size.

Here is the same example reworked with the svg loaded from the assets folder and an android javascript interface exposed so you do callbacks into android code from your svg file.

  WebView webView;

  public class WebAppInterface {
    /** Show a toast from svg */
    @JavascriptInterface
    public void showToast(String toast) {
      Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    webView = (WebView) findViewById(R.id.webView1);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new WebAppInterface(), "Android");

    String svg = loadSvg();
    webView.loadData(svg, "image/svg+xml", "utf-8");
  }

  String loadSvg() {
    try {
      BufferedReader input = new BufferedReader(new InputStreamReader(
          getAssets().open("test.svg")));
      StringBuffer buf = new StringBuffer();
      String s = null;
      while ((s = input.readLine()) != null) {
        buf.append(s);
        buf.append('\n');
      }
      input.close();
      return buf.toString();
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    return null;
  }

and the test.svg file:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="6cm" height="5cm" viewBox="0 0 600 500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Example script01 - invoke an ECMAScript function from an onclick event
  </desc>
  <!-- ECMAScript to change the radius with each click -->
  <script type="application/ecmascript"> <![CDATA[
    function circle_click(evt) {
        Android.showToast("Hello from SVG");
      var circle = evt.target;
      var currentRadius = circle.getAttribute("r");
      if (currentRadius == 100)
        circle.setAttribute("r", currentRadius*2);
      else
        circle.setAttribute("r", currentRadius*0.5);
    }
  ]]> </script>

  <!-- Outline the drawing area with a blue line -->
  <rect x="1" y="1" width="598" height="498" fill="none" stroke="blue"/>

  <!-- Act on each click event -->
  <circle onclick="circle_click(evt)" cx="300" cy="225" r="100"
          fill="red"/>

  <text x="300" y="480" 
        font-family="Verdana" font-size="35" text-anchor="middle">
    Click on circle to change its size
  </text>
</svg>
like image 39
Dan Brough Avatar answered Oct 08 '22 19:10

Dan Brough