How to define click event separately for each path element

≯℡__Kan透↙ 提交于 2019-12-23 10:21:16

问题


I am working with SVG files on Android. Android Studio converts SVG files into XML files containing vector and path elements. An XML file can have multiple "path" elements. The problem starts right here. I want to give each path element the ability to be individually clicked without using webview. (Cause of javascript is risky!) Is there a way to do that?

I cant use clicked pixels colors. Cause they are very variable. I can seperate each path elements to different XML files. But this paths also keep remember of where they are located. And when I wanted to add each XML files into FrameLayout, they are expanding their rectangle edge untill to the phone edge. Even if they have wrap_content in width and height properties.. So onClick events blocked. onClick events works just one. You can check blue edge in the photo. This blue edge same for each imageviews :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/path_one" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/path_two" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/path_three" />
</FrameLayout>

path_one :

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="340dp"
    android:viewportHeight="340"
    android:viewportWidth="800">
    <path
        android:fillAlpha="1"
        android:fillColor="#da241c"
        android:pathData="M52.39,44.01L54.63,41.94L57.68,42.54L64.66,41.57L66.41,42.87L67.51,45.88L72.34,49.65L75.51,48.5L78.38,45.54L80.04,39.15L82.2,37.29L88.55,34.96L92.09,34.57L100.5,29.58L100.87,28.25L102.52,28.39L102.52,28.39L103.01,29L103.01,29L99.86,44.65L97.47,48.72L97.49,51.15L95.74,54.66L95.58,57.53L96.47,59.49L96.47,59.49L94.92,62.8L91.57,62.71L86.49,60.02L76.48,62.25L74.69,65.68L74.09,69.27L69.49,73.59L67.58,77.44L62.61,81.12L57.04,82.69L54.94,84.99L52.22,85.67L52.22,85.67L52.17,82.72L55.49,74.92L52.38,73.87L46.42,74.15L46.42,74.15L42.46,68.99L43.56,60.73L41.5,58.83L42.36,57.78L46.69,57.12L50.78,53.06L53.17,48.89z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />
</vector>

path_two :

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="340dp"
    android:viewportHeight="340"
    android:viewportWidth="800">
    <path
        android:fillAlpha="1"
        android:fillColor="#da241c"
        android:pathData="M65.51,0.31L67.29,0.43L69.07,2.54L70.31,2.65L71.46,5.52L74.69,8.09L76.36,8.08L78.5,11.11L79.06,9.29L80.72,9.11L81.02,8.09L83.07,8.3L84.16,7.07L89.81,8.73L89.13,6.6L90.46,5.69L90.65,6.31L90.81,5.52L92.95,7.36L95.64,6.4L97.64,6.94L98.86,12.3L96.42,12.11L95.82,15.36L98.39,21.01L100.86,24.08L100.16,24.76L100.66,26.19L102.52,28.39L102.52,28.39L100.87,28.25L100.5,29.58L92.09,34.57L88.55,34.96L82.2,37.29L80.04,39.15L78.38,45.54L75.51,48.5L72.34,49.65L67.51,45.88L66.41,42.87L64.66,41.57L57.68,42.54L54.63,41.94L52.39,44.01L52.39,44.01L51.05,42.86L52.28,40.45L51.14,36.11L53.41,32.2L53.03,30.73L55.21,27.9L54.06,26.81L52.37,28.67L51.38,27.75L53.83,24.46L53.44,21.65L54.99,18.26L53.52,15.1L53.8,5.66L53.8,5.66L54.44,3.71L56.24,2.68L56.19,1.3L58.01,0.66L63.53,2.51L63.5,1.29z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />
</vector>

path_three :

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="340dp"
    android:viewportHeight="340"
    android:viewportWidth="800">

    <path
        android:fillAlpha="1"
        android:fillColor="#ea912d"
        android:pathData="M149.16,48.24l13.17,3.21l0.97,-0.56l9.4,2.24l3.93,-0.05l0,0l0.09,2.6l-2.37,3.93l-1.63,0.55l-4.18,-0.92l-2.36,3.82l-3.88,-1l-3.13,0.58l-7.01,8.76l0,0l-1.03,-0.72l-2.56,0.6l1.22,-2.52l-5.9,-2.58l-1.44,-2.14L138.81,62l-0.64,-2.35l1.87,-1.48l0.64,-2.98l1.15,-0.78L140.88,53l0.69,-1.95l3.24,-2.5L149.16,48.24zM103.83,29.47l3.97,4.12l14.47,7.7l2.63,0.46l11.03,5.02l5.3,0.2l1.37,0.79l-0.02,1.47l-3.03,3.02l1.39,1.77l-3.64,6.48l-5.6,1.74l-0.73,0.96l-2.9,-1.3l-5.83,1.08l-1.03,-0.66l-0.32,-2.42l-0.93,-0.04l-1,1.8l-5.09,-3.12l-7.7,-1.98l-6.57,1.16l-3.11,1.77l0,0l-0.9,-1.97l0.17,-2.87l1.74,-3.51l-0.02,-2.43l2.39,-4.07L103.01,29l0,0L103.83,29.47z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />
</vector>

All of them together :

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="340dp"
    android:viewportHeight="340"
    android:viewportWidth="800">
    <path
        android:fillAlpha="1"
        android:fillColor="#da241c"
        android:pathData="M52.39,44.01L54.63,41.94L57.68,42.54L64.66,41.57L66.41,42.87L67.51,45.88L72.34,49.65L75.51,48.5L78.38,45.54L80.04,39.15L82.2,37.29L88.55,34.96L92.09,34.57L100.5,29.58L100.87,28.25L102.52,28.39L102.52,28.39L103.01,29L103.01,29L99.86,44.65L97.47,48.72L97.49,51.15L95.74,54.66L95.58,57.53L96.47,59.49L96.47,59.49L94.92,62.8L91.57,62.71L86.49,60.02L76.48,62.25L74.69,65.68L74.09,69.27L69.49,73.59L67.58,77.44L62.61,81.12L57.04,82.69L54.94,84.99L52.22,85.67L52.22,85.67L52.17,82.72L55.49,74.92L52.38,73.87L46.42,74.15L46.42,74.15L42.46,68.99L43.56,60.73L41.5,58.83L42.36,57.78L46.69,57.12L50.78,53.06L53.17,48.89z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />

    <path
        android:fillAlpha="1"
        android:fillColor="#da241c"
        android:pathData="M65.51,0.31L67.29,0.43L69.07,2.54L70.31,2.65L71.46,5.52L74.69,8.09L76.36,8.08L78.5,11.11L79.06,9.29L80.72,9.11L81.02,8.09L83.07,8.3L84.16,7.07L89.81,8.73L89.13,6.6L90.46,5.69L90.65,6.31L90.81,5.52L92.95,7.36L95.64,6.4L97.64,6.94L98.86,12.3L96.42,12.11L95.82,15.36L98.39,21.01L100.86,24.08L100.16,24.76L100.66,26.19L102.52,28.39L102.52,28.39L100.87,28.25L100.5,29.58L92.09,34.57L88.55,34.96L82.2,37.29L80.04,39.15L78.38,45.54L75.51,48.5L72.34,49.65L67.51,45.88L66.41,42.87L64.66,41.57L57.68,42.54L54.63,41.94L52.39,44.01L52.39,44.01L51.05,42.86L52.28,40.45L51.14,36.11L53.41,32.2L53.03,30.73L55.21,27.9L54.06,26.81L52.37,28.67L51.38,27.75L53.83,24.46L53.44,21.65L54.99,18.26L53.52,15.1L53.8,5.66L53.8,5.66L54.44,3.71L56.24,2.68L56.19,1.3L58.01,0.66L63.53,2.51L63.5,1.29z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />

    <path
        android:fillAlpha="1"
        android:fillColor="#ea912d"
        android:pathData="M149.16,48.24l13.17,3.21l0.97,-0.56l9.4,2.24l3.93,-0.05l0,0l0.09,2.6l-2.37,3.93l-1.63,0.55l-4.18,-0.92l-2.36,3.82l-3.88,-1l-3.13,0.58l-7.01,8.76l0,0l-1.03,-0.72l-2.56,0.6l1.22,-2.52l-5.9,-2.58l-1.44,-2.14L138.81,62l-0.64,-2.35l1.87,-1.48l0.64,-2.98l1.15,-0.78L140.88,53l0.69,-1.95l3.24,-2.5L149.16,48.24zM103.83,29.47l3.97,4.12l14.47,7.7l2.63,0.46l11.03,5.02l5.3,0.2l1.37,0.79l-0.02,1.47l-3.03,3.02l1.39,1.77l-3.64,6.48l-5.6,1.74l-0.73,0.96l-2.9,-1.3l-5.83,1.08l-1.03,-0.66l-0.32,-2.42l-0.93,-0.04l-1,1.8l-5.09,-3.12l-7.7,-1.98l-6.57,1.16l-3.11,1.77l0,0l-0.9,-1.97l0.17,-2.87l1.74,-3.51l-0.02,-2.43l2.39,-4.07L103.01,29l0,0L103.83,29.47z"
        android:strokeAlpha="1"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="0.5" />
</vector>

回答1:


You can use RichPath library, it has an integrated OnClickListener which passes clicked path element. GitHub link: https://github.com/tarek360/RichPath

Define SVG as VectorDrawable and add it to XML

 <com.richpath.RichPathView
    android:id="@+id/ic_notifications"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:vector="@drawable/ic_notifications" />

And set setOnPathClickListener in code:

richPathView.setOnPathClickListener(new RichPath.OnPathClickListener() {
 @Override
public void onClick(RichPath richPath) {
   if (richPath.getName().equals("path_name")) {
       //TODO do an action when a specific path is clicked.
   }
 }
});



回答2:


As far as I am aware, there is no way to achieve what you want using VectorDrawables. I think you are probably going to have to load the SVG into a WebView.

However you don't have to use any JavaScript. The WebView widget has a way to intercept link requests. See Handling Page Navigation in the WebView documentation.

You would just need to surround your <path> elements with a <a> link element.

<svg ...etc...>
    <a xlink:href="SOME_URL">
        <path d="..."/>
    </a>
    ....
</svg>

Then intercept "SOME_URL", whatever it is, in your shouldOverrideUrlLoading() method.




回答3:


If you seperate all paths into different ImageView-s, than you can override all of the IV's onTouchListener like this:

firstImg.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
        int color = bmp.getPixel((int) event.getX(), (int) event.getY());
        if (color == Color.TRANSPARENT)
            return false;
        else {
            // here you can handle your click event
            return true;
        }
    }
});

But be careful, this approach uses a LOT of resources because every touch event goes through several onTouch listeners.



来源:https://stackoverflow.com/questions/49959050/how-to-define-click-event-separately-for-each-path-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!