【问题标题】:How to define click event separately for each path element如何为每个路径元素分别定义点击事件
【发布时间】:2023-03-09 22:11:01
【问题描述】:

我正在 Android 上处理 SVG 文件。 Android Studio 将 SVG 文件转换为包含矢量和路径元素的 XML 文件。一个 XML 文件可以有多个“路径”元素。问题从这里开始。我想让每个路径元素能够在不使用 webview 的情况下单独单击。 (javascript 的原因是risky!)有没有办法做到这一点?

我不能使用点击的像素颜色。因为它们非常多变。 我可以将每个路径元素分隔到不同的 XML 文件中。但是这些路径也会记住它们的位置。当我想将每个 XML 文件添加到 FrameLayout 中时,它们会将矩形边缘扩展到手机边缘。即使他们在宽度和高度属性中有 wrap_content 。所以 onClick 事件被阻止。 onClick 事件只有一个。您可以检查照片中的蓝色边缘。每个图像视图的蓝色边缘相同:

<?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>

路径三:

<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>

所有这些都在一起:

<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>

【问题讨论】:

  • 你有答案了吗?

标签: android svg android-vectordrawable


【解决方案1】:

你可以使用 RichPath 库,它有一个集成的 OnClickListener,它传递点击的路径元素。 GitHub链接:https://github.com/tarek360/RichPath

将 SVG 定义为 VectorDrawable 并将其添加到 XML

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

并在代码中设置setOnPathClickListener:

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.
   }
 }
});

【讨论】:

  • 有没有办法为 RichPathView 添加缩放功能?
  • 如果您需要缩放功能,我建议您查看github.com/davemorrissey/subsampling-scale-image-view。
  • 好的,谢谢,这个库是否也像richpath一样支持路径点击检测?
  • 不,这个库使用 PNG 光栅图像。
  • 嗯,对我来说就是这样。我必须结合缩放 svg 并检测点击了哪个路径,可以在 Android 中执行吗?
【解决方案2】:

据我所知,没有办法使用 VectorDrawables 来实现您想要的。我认为您可能必须将 SVG 加载到 WebView 中。

但是,您不必使用任何 JavaScript。 WebView 小部件有一种拦截链接请求的方法。请参阅 WebView 文档中的 Handling Page Navigation。

您只需用&lt;a&gt; 链接元素包围您的&lt;path&gt; 元素。

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

然后在您的shouldOverrideUrlLoading() 方法中拦截“SOME_URL”,无论它是什么。

【讨论】:

    【解决方案3】:

    如果您将所有路径分隔到不同的 ImageView-s 中,则可以像这样覆盖所有 IV 的 onTouchListener:

    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;
            }
        }
    });
    

    但请注意,这种方法会占用大量资源,因为每个触摸事件都会经过多个 onTouch 侦听器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 2015-09-14
      • 2011-03-04
      • 1970-01-01
      • 2011-11-11
      相关资源
      最近更新 更多