5

私の Android アプリケーションでは、以下のように世界中に 3 つの不規則な形状があります。

ここに画像の説明を入力

そこで、この画像全体をレイアウトに配置しました。Globe is just an image .There is no role of globe here.ここで、世界中にあるそれぞれの不規則な形の画像の上に 1 つのボタンを配置したいと考えています。

ボタンは常に長方形ですがI want to get touch event for irregular shape,not for rectangular area.、これら3つの不規則な形状に3つのボタンを配置するにはどうすればよいですか、または解決策はありますか? ボタンごとに異なるイベントをアクティビティで処理できるようにするには?

このタスクを達成する方法がわかりません。これについて私を案内してください。

アドバイスや提案はありますか?

どんな助けでも大歓迎です。

4

4 に答える 4

1

私はこれをテストしていませんが、うまくいくと思います。微調整して修正する必要があると確信しています。

3 つのボタンがエイリアシングのない 3 つの異なる色であり、他のすべてのピクセルが純粋な黒である背景画像のコピーを作成します。JPG 圧縮アーティファクトが発生しないように、PNG である必要があります。これがあなたのマスクになります。ボタンが 3 つしかないので、純粋な赤、緑、青を使用できます。縦横比が同じである限り、おそらく元の画像よりも解像度が低くなる可能性があります。

ImageView をサブクラス化し、代わりにサブクラスを使用して背景を描画します。ImageView のサブクラス化されたバージョンを、マスク イメージをビットマップとして渡します。

class TouchMaskImageView extends ImageView {
    ...constructors

    public void setTouchMask(Bitmap mask){
        this.mMask = mask;
    }

    public interface OnTouchedListener{
        public void onTouched(MotionEvent event, int colorTouched);
        public void onTouchCanceled();
    }

    public void setOnTouchedListener(OnTouchedListener listener){
        this.mOnTouchedListener = listener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (mOnTouchedListener  != null && mMask != null ) {
            if (x >=0 && x < (float)getWidth() &&
                y >=0 && y < (float)getHeight()) {
                //Next two lines will be more complicated if 
                  // you aren't using scaleType fitXY
                int maskX = (int) x * mMask.getWidth() / getWidth();
                int maskY = (int) y * mMask.getWidth() / getHeight();
                int maskColor = mask.getPixel(maskX, maskY);
                mOnTouchedListener.onTouched(event, maskColor);
            } else if (event.getAction()==MotionEvent.UP){
                //released finger outside image view
                mOnTouchedListener.onTouchCanceled();
            }
        }
    }
}

これで、ボタンと同様のタッチ ロジックを処理する OnTouchedListener を作成できます。状態を追跡する必要があります。以下に例を示しますが、マルチタッチがあるとこれが壊れるかどうかはわかりません。また、最初の指のアクション マスクを設定し、getAction() の代わりに getActionMasked() を使用する必要がある場合があります。

public void onTouched(MotionEvent event, int colorTouched){
    switch(mState){
    case STATE_WAITING:
        if (event.getAction()==MotionEvent.ACTION_DOWN){
            switch (colorTouched){
            case 0xffff0000: //red
                mTouchMaskImageView.setImageResource(R.drawable.redButtonDown);
                mState = STATE_LATCHED_RED;
                break;
            case 0xff00ff00: //green
                mTouchMaskImageView.setImageResource(R.drawable.greenButtonDown);
                mState = STATE_LATCHED_GREEN;
                break;
            case 0xff0000ff: //blue
                mTouchMaskImageView.setImageResource(R.drawable.blueButtonDown);
                mState = STATE_LATCHED_BLUE;
                break;
            }
        }
        break;
   case STATE_LATCHED_RED:
        switch (event.getAction()){
        case (MotionEvent.ACTION_MOVE):
            if (colorTouched = 0xffff0000)
                mTouchMaskImageView.setImageResource(R.drawable.redButtonDown);
            else
                mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
            break;
        case (MotionEvent.ACTION_UP)
            if (colorTouched = 0xffff0000)
                performRedButtonAction();
            mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
            mState = STATE_WAITING;
            break;
        }
        break;
   case etc. for other two latched colors...
        break;
   }
}

public void onTouchCanceled(){
    mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
    mState = STATE_WAITING;
}

4 つの可能な状態を表すには、イメージの 4 つの異なるコピーが必要になるため、これはやや大雑把です。時間をかけてメモリを節約し、より高速に実行したい場合は、正しい位置にオーバーレイされた 3 つのボタンの個別の画像ビューを使用してレイアウトを設定し、画像の変更をターゲットにすることができます。しかし、どんな画面サイズにも完全に合わせる必要があることを考えると、これは非常に困難です。

于 2013-08-28T14:30:33.503 に答える
0

Photoshop で画像をスライスしてから、その画像を webview に配置すると効果がありますか?

于 2013-09-03T18:23:22.977 に答える
0

上記の回答から、ヒントを得て、最終的に以下のように解決策を得ました。

私がしたことは次のとおりです。

xml ファイルで使用される RelativeLayout

以下のようにImageViewを使用しました:

  <ImageView
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/glob2"
        android:layout_marginBottom="24dp"
        android:layout_marginLeft="80.5dp"
        android:contentDescription="@string/profile_picture_description"
        android:src="@drawable/pick_matches_background" />

ここでは、それに応じて余白を設定します(左/右/下/上)。

活動では、

宣言する

Bitmap btmp; and
ImageView img;

onCreate メソッドでは、

 // initialized image view
img = (ImageView) findViewById(R.id.btn1);
img.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

       // call your method here

  }
});

StateListDrawable sdCreateTrip = (StateListDrawable) img
            .getDrawable();

btmp = ((BitmapDrawable) sdCreateTrip.getCurrent())
            .getBitmap();

これで準備完了です。

于 2013-09-04T11:39:27.477 に答える
0

FLAG_WINDOW_IS_OBSCUREDフラグは過去に私にとってはうまくいきましたが、うまくいくには少し時間がかかるかもしれません. 試してみる価値はあるかもしれませんが、正直に言うと、何が隠されているか、隠されていないかを正確に判断する方法がまだわからないため、ここでは適用できない可能性があります。

static OnTouchListener listenerMotionEvent = new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if ( (motionEvent.getFlags() | MotionEvent.FLAG_WINDOW_IS_OBSCURED) != MotionEvent.FLAG_WINDOW_IS_OBSCURED ) {
            return false;
            // View is not obscured so we pass on the event
        }

        // Process the motion event here and return true if you consume it
};
于 2013-08-25T21:49:09.803 に答える