可点击的图像区域

问题描述 投票:24回答:5

我正在设计一个GUI远程控制,但我没有为每个远程按钮制作单独的按钮,而是希望获得一个完整的就绪远程图像并设置它的某些部分可点击。有没有办法而不是动作事件呢?

android onclicklistener imagemap
5个回答
35
投票

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

解决方案1:

你可以屏蔽图像并获得图像下面的像素颜色。最后你可以知道哪个区域被点击了。

在这里,每当发生单击时,您可以检查background image的像素颜色并将其与预定义的颜色集匹配,以了解已单击的区域。

前景图片:

背景图片:

可点击区域:

仍然困惑?

参考:我建议你通过this教程。

解决方案2:

您可以使用坐标映射图像,因此您可以获得已单击区域的信息。

示例:使用坐标映射图像

如果您不了解坐标,可以从here创建您的mappedimage

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

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

参考:请看看Android Image Mapping

我希望它会有所帮助!!


8
投票

你仍然可以使用按钮。

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

在XML中

<Button android:visibility="invisible"/>

要么

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

2
投票

我遇到了同样的挑战,并用图书馆"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();
        }
    }
...
}

0
投票

改善@sealz的回复,这里是我的回答:

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

0
投票

如果单击矩形就足够了,那么通过扩展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将它们添加到视图中

© www.soinside.com 2019 - 2024. All rights reserved.