2013-07-29 4 views
9

私は非常に難しいことに、ビットマップオーバーレイを画面に表示するように管理しています。私はまた、タッチ入力を得ることができますが、それは画面上のどこにでもタッチ入力を取得します。XとY座標がボタンの中にあるかどうかを確認するには?

画面に表示されているビットマップ上にタッチがあったかどうかを確認する方法を知りたいと思います。

サービスとビューのクラスは以下のとおりです。私が考えたと思ったが、私はそれを行うための方法を考えることができませんでしたしている:(

package <package>; 

import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PixelFormat; 
import android.graphics.Rect; 
import android.os.IBinder; 
import android.support.v4.app.NotificationCompat; 
import android.view.Gravity; 
import android.view.MotionEvent; 
import android.view.ViewGroup; 
import android.view.WindowManager; 
import android.widget.Toast; 

public class MyService extends Service { 
    ButtonView mView; 
    Bitmap bit; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     bit = BitmapFactory.decodeResource(getResources(), R.drawable.button); 

     NotificationCompat.Builder builder = new NotificationCompat.Builder(
       this); 
     builder.setContentTitle("Ingress Tools Running"); 
     builder.setContentText("Click to stop Ingress Tools"); 
     builder.setSmallIcon(R.drawable.ic_launcher); 
     builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(
       this, StopActivity.class), 0)); 
     NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     manager.notify(1, builder.build()); 

     mView = new ButtonView(this, bit); 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.FILL_PARENT, 
       WindowManager.LayoutParams.FILL_PARENT, 
       WindowManager.LayoutParams.TYPE_PHONE, 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
       PixelFormat.TRANSLUCENT); 
     params.gravity = Gravity.RIGHT; 
     params.setTitle("Load Average"); 
     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.addView(mView, params); 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Toast.makeText(getBaseContext(), "onDestroy", Toast.LENGTH_LONG).show(); 
     if (mView != null) { 
      ((WindowManager) getSystemService(WINDOW_SERVICE)) 
        .removeView(mView); 
      mView = null; 
     } 
    } 
} 

class ButtonView extends ViewGroup { 
    private Paint mLoadPaint; 
    private Rect r; 
    private Bitmap bit; 

    public ButtonView(Context context, Bitmap bit) { 
     super(context); 
     Toast.makeText(context, "HUDView", Toast.LENGTH_LONG).show(); 

     mLoadPaint = new Paint(); 
     mLoadPaint.setAntiAlias(true); 
     mLoadPaint.setTextSize(10); 
     mLoadPaint.setARGB(255, 255, 0, 0); 
     r = new Rect(); 
     r.set(380, 134, 468, 213); 
     this.bit = bit; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     //canvas.drawColor(Color.BLACK); 

     canvas.drawBitmap(bit, 100, 100, null); 
    } 

    @Override 
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     int area = bit.getWidth() * bit.getHeight(); 


     //if (event.getY() <= maxY && event.getX() <= maxX) { 
      Toast.makeText(getContext(), "Open tools: ", Toast.LENGTH_LONG) 
        .show(); 

     //} 
     return true; 

    } 
} 

答えて

11

はなく直接ViewGroupFrameLayout(またはViewGroupの他のサブクラス)を使用することを検討してください。onLayout方法のあなたの現在の実装であるためこれは正しいものではありません。子ビューの表示に関する問題につながります。

Rectを初期化して、Bitmapの左、上、右、下の位置を保存する必要があります。現在、変数rが初期化されていますが、どこでも使用されていません。

だから、あなたはこのようにそれを初期化することができます。onTouchEventで今

r = new Rect(100, 100, 100 + bit.getWidth(), 100 + bit.getHeight()); 

あなただけ確認することができます:if文

r.contains((int) event.getX(), (int) event.getY()); 
+0

うーむ、これは動作しますが、今は何もタッチイベントをrecievesないために動作します。のように、私は画面上の何かをクリックすることはできません(これを追加する前にこれが起こったかもしれませんが)。 –

+0

@LiamW 'MotionEvent'をさらに伝播させたい場合、' onTouchEvent'からfalseを返すべきです。 –

+0

if文の外側でfalseを返しますが、画像の外側をタッチすると何も起こりません。 –

1

はあなたがチェックしたい、そのボタン上のメソッドif(r.contains(x, y))で使用してください。このメソッドは、xとy点が矩形rの内側にある場合にtrueを返します。そのクラス内でパブリックメソッドを作成することもできます。ボタンオブジェクト参照を使用してButtonViewクラスの外にアクセスできます。

11
Rect rect = new Rect(); 
getHitRect(rect); 
if (rect.contains((int) event.getX(), (int) event.getY())) {} 

getHitRect(Rect)を使用できます。ヒット矩形を親の座標で返します。 Hereドキュメント

+1

通常、この答えは行く方法です。しかし、彼は 'View'の代わりに' Bitmap'を描くので、 'getHitRect'を使うことはできません。 –

-1

「タッチイベント」が発生すると、すべてのビューのツリーが表示されます。 F.e. LinearレイアウトとImageViewがあり、ユーザーがImageViewで画面にタッチすると、イベントインターセプトに触れ、まずLinearLayourで処理してからImageViewで処理します。

イベントf.eをブロックする場合は、ビットマップでonTouchEventをオーバーライドしてtrue値を返す必要があります。これは、このイベントを処理したことを意味し、LinearLayoutでは使用できません。

image.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View view, MotionEvent motionEvent) { 
       return true; // attentively read documentation for onTouc interface 
      } 
     }); 
7

これは、任意のビュー

@Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 

      if (event.getAction() == MotionEvent.ACTION_UP) { 
       if (inViewInBounds(myButtonView, (int) event.getRawX(), (int) event.getRawY())) { 
        // User moved outside bounds 
        Log.e("dispatchTouchEvent", "you touched inside button"); 
       } else { 
        Log.e("dispatchTouchEvent", "you touched outside button"); 
       } 

     } 
     return super.dispatchTouchEvent(event); 
    } 

Rect outRect = new Rect(); 
    int[] location = new int[2]; 


private boolean inViewInBounds(View view, int x, int y) { 
     view.getDrawingRect(outRect); 
     view.getLocationOnScreen(location); 
     outRect.offset(location[0], location[1]); 
     return outRect.contains(x, y); 
    } 
関連する問題