图片的可点击区域

Posted

技术标签:

【中文标题】图片的可点击区域【英文标题】:clickable area of image 【发布时间】:2013-05-16 06:22:35 【问题描述】:

我正在设计一个 GUI 遥控器,但我不想为每个遥控器按钮制作单独的按钮,而是想要获得一个完整的远程图像并将其某些部分设置为可点击。 有没有办法而不是运动事件来做到这一点?

【问题讨论】:

您想在一张图片中完成所有内容吗? 是他们以某种方式将图像拆分为行和列的方法吗? @OutflorksUsus:您介意整个图像保持可点击状态,但您肯定能获得点击区域的准确信息吗? @MehulJoisar 如果这在应用程序运行时没有做出错误的操作,那么没问题 我想过使用 gridview 布局,但我无法为其设置背景图像 【参考方案1】:

我有 2 个解决方案可以满足您的要求。在这两种解决方案中,整个图像都保持可点击状态,但您可以获得有关点击区域的信息。

解决方案 1:

您可以屏蔽图像并获取图像下方的像素颜色。这样最终您就可以知道点击了哪个区域。

在这里,每当点击时,您可以检查background image的像素颜色,并与预定义的颜色组匹配,以了解点击了哪个区域。

前景图像:

背景图片:

可点击区域:

还是一头雾水?

参考: 我建议您阅读this 教程。

解决方案 2:

你可以用坐标来映射你的图片,从而可以得到被点击区域的信息。

示例: 带坐标的MappedImage

如果你不知道坐标,你可以从here创建你的mappedimage

堪萨斯州的坐标看起来像这样,

        <area shape="poly" coords="243,162,318,162,325,172,325,196,244,196" id="@+id/area14" name = "Kansas"/>

参考: 请看android Image Mapping。

希望对你有帮助!!

【讨论】:

谢谢!知道如何在钛合金应用程序中使用这些方法吗? 如果我们必须缩放图像并获取像素怎么办?它返回相同的颜色吗?【参考方案2】:

您仍然可以使用按钮。

您可以将它们放置在图像上的正确位置并使它们不可见。

在 XML 中

<Button android:visibility="invisible"/>

或者

Button mybutton = (Button) v1;
mybutton.setVisibility(View.INVISIBLE);

【讨论】:

我有一个相对的布局,里面有一些按钮。如果我在相对布局上设置背景图像并将按钮设置为不可见,则不会触发 onClick。当我将它们设置为可见时,它们会显示。 这不取决于您如何使按钮不可见吗?即,如果您将visibility 属性设置为gone(或invisible),则它们无法被点击,但如果您尝试将按钮的背景设置为100% 透明,我希望您仍然会得到点击事件(??) @sealz 我喜欢这个解决方案,但可见性不起作用。我使背景透明并且效果很好。【参考方案3】:

我遇到了同样的挑战,并通过库"PhotoView" 解决了它,您可以在其中收听

onPhotoTap(View view, float x, float y) 

事件并检查选项卡是否在您的图像区域内,然后执行某些任务。

我创建了一个库来帮助其他开发人员更快地实现这些功能。在 Github 上:ClickableAreasImages

此库可让您定义图像中的可点击区域,将对象与其关联并监听该区域上的触摸事件。

如何使用库:

public class MainActivity extends AppCompatActivity implements OnClickableAreaClickedListener 

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

        // Add image
        ImageView image = (ImageView) findViewById(R.id.imageView);
        image.setImageResource(R.drawable.simpsons);

        // Create your image
        ClickableAreasImage clickableAreasImage = new ClickableAreasImage(new PhotoViewAttacher(image), this);

        // Initialize your clickable area list
        List<ClickableArea> clickableAreas = new ArrayList<>();

        // Define your clickable areas
        // parameter values (pixels): (x coordinate, y coordinate, width, height) and assign an object to it
        clickableAreas.add(new ClickableArea(500, 200, 125, 200, new Character("Homer", "Simpson")));
        clickableAreas.add(new ClickableArea(600, 440, 130, 160, new Character("Bart", "Simpson")));
    

    // Listen for touches on your images:
    @Override
    public void onClickableAreaTouched(Object item) 
        if (item instanceof Character) 
            String text = ((Character) item).getFirstName() + " " + ((Character) item).getLastName();
            Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
        
    
...

【讨论】:

如果我需要检查非矩形区域(如圆形)中的点击怎么办?它适用于您的图书馆吗?谢谢。【参考方案4】:

如果单击矩形就足够了,那么通过扩展 ImageView 可以很容易地实现。下面是一个简单的实现,不考虑可访问性。

观点:

package com.example.letzterwille.views;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

import java.util.HashMap;
import java.util.Map;

import androidx.annotation.Nullable;

public class ClickableAreaImageView extends ImageView 

    Map< Rect, Runnable > areaEffects = new HashMap<>();

    public ClickableAreaImageView( Context context ) 
        super( context );
    

    public ClickableAreaImageView( Context context, @Nullable AttributeSet attrs ) 
        super( context, attrs );
    

    public ClickableAreaImageView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) 
        super( context, attrs, defStyleAttr );
    

    public ClickableAreaImageView( Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes ) 
        super( context, attrs, defStyleAttr, defStyleRes );
    

    public void addAreaEffect( Rect target, Runnable event ) 
        areaEffects.put( target, event );
    

    @Override
    public boolean onTouchEvent( MotionEvent event ) 
        if ( event.getAction() == MotionEvent.ACTION_DOWN ) 
            int x = ( int ) event.getX();
            int y = ( int ) event.getY();

            for ( Map.Entry< Rect, Runnable > entry : areaEffects.entrySet() ) 
                Rect rect = entry.getKey();
                if ( rect.contains( x, y ) ) entry.getValue().run();
            
        

        return super.onTouchEvent( event );
    

在您的 XML 或 Java 中,像使用普通 ImageView 一样使用它。

然后,您必须注册点击操作。我想参加特定的活动,在 Kotlin 中看起来像这样:

class MenuSelection : AppCompatActivity() 

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_menu_selection)
        val areaImage = findViewById<ClickableAreaImageView>(R.id.menuSelectionImage)

        areaImage.addAreaEffect(Rect(530, 100, 1080, 800), makeRunnable(SettingsActivity::class.java))
        areaImage.addAreaEffect(Rect(30, 80, 430, 700), makeRunnable(StatsActivity::class.java))
    

    private fun makeRunnable(activity: Class<*>): Runnable 
        return Runnable 
            val intent = Intent(this, activity)
            startActivity(intent)
            overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.slide_out_to_top);
        
    

一般情况下,通过定义矩形来使用它,当点击矩形时执行一个Runnable,然后通过ClickableAreaImageView.addAreaEffect将它们添加到视图中

【讨论】:

很好的例子。谢谢。为什么要混合 java 和 kotlin。它使它变得比必要的复杂。【参考方案5】:

改进@sealz 回复,这是我的答案:

<RelativeLayout 
    android:layout_
    android:layout_
    >
    <LinearLayout 
        android:layout_
        android:layout_
        android:orientation="horizontal"
        android:layout_centerInParent="true"
        android:layout_alignTop="@+id/mail"
        android:layout_alignBottom="@+id/mail"
        >
        <Button
            android:id="@+id/leftMail"
            android:layout_
            android:layout_
            android:layout_weight=".5"
            android:background="@android:color/transparent"
            />
        <Button
            android:id="@+id/rightMail"
            android:layout_
            android:layout_
            android:layout_weight=".5"
            android:background="@android:color/transparent"    
            />
        </LinearLayout>
    <ImageView 
       android:id="@+id/mail"
        android:layout_
        android:layout_
        android:src="@drawable/mail1600x600"
        android:layout_centerInParent="true"
        />
</RelativeLayout>

【讨论】:

以上是关于图片的可点击区域的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 中图像按钮的可点击区域

增加 TextField 的可点击区域

如何使按钮的可点击区域成为按钮框架

Swiftui 有没有办法改变按钮的可点击区域

mapbox GL js中线串周围的可点击区域

SwiftUI 中 Button 和 Image 的可点击区域