web-dev-qa-db-ja.com

画像のクリック可能な領域

gUIリモコンを設計していますが、リモートボタンごとに個別のボタンを作成するのではなく、完全なリモートイメージを取得し、その特定の部分をクリック可能に設定します。これを行うにはモーションイベントではなく方法がありますか?

26
Outflorks Usus

私はあなたの要件に2つの解決策を持っています。両方で、画像全体がクリック可能なままですが、クリックされた領域に関する情報を取得できます。

ソリューション1:

画像をマスクして、画像の下にあるピクセルcolorを取得できます。これにより、最終的にどの領域がクリックされたかを知ることができます。

ここでは、クリックが発生するたびに、background imageのピクセルカラーを確認し、それを事前定義されたカラーセットと照合して、クリックされた領域を知ることができます。

前景画像: Foreground image

背景画像: Background image

クリック可能な領域: Representing clickable area

まだ混乱していますか?

参考:this チュートリアルを実行することをお勧めします。

ソリューション2:

座標で画像をマッピングできるので、クリックしたエリアの情報を取得できます。

例:MappedImage with coordinates

座標がわからない場合は、マッピングされたイメージを here から作成できます

カンザス州の座標は次のようになります

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

MappedImage with co-ordinates

参照:Android Image Mapping をご覧ください。

お役に立てれば幸いです。

35
Mehul Joisar

ボタンは引き続き使用できます。

画像の上に適切な場所に配置して、非表示にすることができます。

XMLで

<Button Android:visibility="invisible"/>

または

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

同じ問題があり、ライブラリ "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();
        }
    }
...
}
2
lukle

四角形をクリックするだけで十分な場合は、ImageViewを拡張することでこれを簡単に実現できます。以下は、アクセシビリティに関係なく、単純な実装です。

景色:

パッケージ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を介してビューに追加します。

0
Kjeld Schmidt

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